From 9ff82036f7872b472eea4907c062b4e7551001c7 Mon Sep 17 00:00:00 2001 From: Yuan Tang Date: Mon, 24 Mar 2025 12:08:50 -0400 Subject: [PATCH 01/45] docs: Simplify vLLM deployment in K8s deployment guide (#1655) # What does this PR do? * Removes the use of `huggingface-cli` * Simplifies HF cache mount path * Simplifies vLLM server startup command * Separates PVC/secret creation from deployment/service * Fixes a typo: "pod" should be "deployment" Signed-off-by: Yuan Tang --- .../distributions/kubernetes_deployment.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/source/distributions/kubernetes_deployment.md b/docs/source/distributions/kubernetes_deployment.md index 6cca2bc47..1b4467934 100644 --- a/docs/source/distributions/kubernetes_deployment.md +++ b/docs/source/distributions/kubernetes_deployment.md @@ -8,7 +8,7 @@ First, create a local Kubernetes cluster via Kind: kind create cluster --image kindest/node:v1.32.0 --name llama-stack-test ``` -Start vLLM server as a Kubernetes Pod and Service: +First, create a Kubernetes PVC and Secret for downloading and storing Hugging Face model: ```bash cat < Date: Mon, 24 Mar 2025 15:42:55 -0400 Subject: [PATCH 02/45] feat: Support "stop" parameter in remote:vLLM (#1715) # What does this PR do? This adds support for "stop" parameter: https://platform.openai.com/docs/api-reference/completions/create#completions-create-stop ## Test Plan ``` tests/integration/inference/test_text_inference.py::test_text_completion_non_streaming[txt=8B-inference:completion:sanity] PASSED [ 5%] tests/integration/inference/test_text_inference.py::test_text_completion_streaming[txt=8B-inference:completion:sanity] PASSED [ 11%] tests/integration/inference/test_text_inference.py::test_text_completion_stop_sequence[txt=8B-inference:completion:stop_sequence] PASSED [ 16%] tests/integration/inference/test_text_inference.py::test_text_completion_log_probs_non_streaming[txt=8B-inference:completion:log_probs] PASSED [ 22%] tests/integration/inference/test_text_inference.py::test_text_completion_log_probs_streaming[txt=8B-inference:completion:log_probs] PASSED [ 27%] tests/integration/inference/test_text_inference.py::test_text_completion_structured_output[txt=8B-inference:completion:structured_output] PASSED [ 33%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_non_streaming[txt=8B-inference:chat_completion:non_streaming_01] PASSED [ 38%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_non_streaming[txt=8B-inference:chat_completion:non_streaming_02] PASSED [ 44%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_first_token_profiling[txt=8B-inference:chat_completion:ttft] ^TPASSED [ 50%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_streaming[txt=8B-inference:chat_completion:streaming_01] PASSED [ 55%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_streaming[txt=8B-inference:chat_completion:streaming_02] PASSED [ 61%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_with_tool_calling_and_non_streaming[txt=8B-inference:chat_completion:tool_calling] PASSED [ 66%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_with_tool_calling_and_streaming[txt=8B-inference:chat_completion:tool_calling] PASSED [ 72%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_with_tool_choice_required[txt=8B-inference:chat_completion:tool_calling] PASSED [ 77%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_with_tool_choice_none[txt=8B-inference:chat_completion:tool_calling] PASSED [ 83%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_structured_output[txt=8B-inference:chat_completion:structured_output] PASSED [ 88%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_tool_calling_tools_not_in_request[txt=8B-inference:chat_completion:tool_calling_tools_absent-True] PASSED [ 94%] tests/integration/inference/test_text_inference.py::test_text_chat_completion_tool_calling_tools_not_in_request[txt=8B-inference:chat_completion:tool_calling_tools_absent-False] PASSED [100%] =============================================================== 18 passed, 3 warnings in 755.79s (0:12:35) =============================================================== ``` --------- Signed-off-by: Yuan Tang --- docs/_static/llama-stack-spec.html | 19 ++++++++++--- docs/_static/llama-stack-spec.yaml | 17 ++++++++++++ llama_stack/models/llama/datatypes.py | 12 +++++++++ .../utils/inference/openai_compat.py | 3 +++ .../inference/test_text_inference.py | 27 +++++++++++++++++++ .../test_cases/inference/completion.json | 5 ++++ 6 files changed, 79 insertions(+), 4 deletions(-) diff --git a/docs/_static/llama-stack-spec.html b/docs/_static/llama-stack-spec.html index 8a46a89ad..64b06e901 100644 --- a/docs/_static/llama-stack-spec.html +++ b/docs/_static/llama-stack-spec.html @@ -4053,22 +4053,33 @@ "type": "object", "properties": { "strategy": { - "$ref": "#/components/schemas/SamplingStrategy" + "$ref": "#/components/schemas/SamplingStrategy", + "description": "The sampling strategy." }, "max_tokens": { "type": "integer", - "default": 0 + "default": 0, + "description": "The maximum number of tokens that can be generated in the completion. The token count of your prompt plus max_tokens cannot exceed the model's context length." }, "repetition_penalty": { "type": "number", - "default": 1.0 + "default": 1.0, + "description": "Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics." + }, + "stop": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence." } }, "additionalProperties": false, "required": [ "strategy" ], - "title": "SamplingParams" + "title": "SamplingParams", + "description": "Sampling parameters." }, "SamplingStrategy": { "oneOf": [ diff --git a/docs/_static/llama-stack-spec.yaml b/docs/_static/llama-stack-spec.yaml index 0b8f90490..78de9afef 100644 --- a/docs/_static/llama-stack-spec.yaml +++ b/docs/_static/llama-stack-spec.yaml @@ -2787,16 +2787,33 @@ components: properties: strategy: $ref: '#/components/schemas/SamplingStrategy' + description: The sampling strategy. max_tokens: type: integer default: 0 + description: >- + The maximum number of tokens that can be generated in the completion. + The token count of your prompt plus max_tokens cannot exceed the model's + context length. repetition_penalty: type: number default: 1.0 + description: >- + Number between -2.0 and 2.0. Positive values penalize new tokens based + on whether they appear in the text so far, increasing the model's likelihood + to talk about new topics. + stop: + type: array + items: + type: string + description: >- + Up to 4 sequences where the API will stop generating further tokens. The + returned text will not contain the stop sequence. additionalProperties: false required: - strategy title: SamplingParams + description: Sampling parameters. SamplingStrategy: oneOf: - $ref: '#/components/schemas/GreedySamplingStrategy' diff --git a/llama_stack/models/llama/datatypes.py b/llama_stack/models/llama/datatypes.py index f762eb50f..fcbe44b07 100644 --- a/llama_stack/models/llama/datatypes.py +++ b/llama_stack/models/llama/datatypes.py @@ -195,10 +195,22 @@ register_schema(SamplingStrategy, name="SamplingStrategy") @json_schema_type class SamplingParams(BaseModel): + """Sampling parameters. + + :param strategy: The sampling strategy. + :param max_tokens: The maximum number of tokens that can be generated in the completion. The token count of + your prompt plus max_tokens cannot exceed the model's context length. + :param repetition_penalty: Number between -2.0 and 2.0. Positive values penalize new tokens + based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics. + :param stop: Up to 4 sequences where the API will stop generating further tokens. + The returned text will not contain the stop sequence. + """ + strategy: SamplingStrategy = Field(default_factory=GreedySamplingStrategy) max_tokens: Optional[int] = 0 repetition_penalty: Optional[float] = 1.0 + stop: Optional[List[str]] = None class CheckpointQuantizationFormat(Enum): diff --git a/llama_stack/providers/utils/inference/openai_compat.py b/llama_stack/providers/utils/inference/openai_compat.py index b264c7312..07976e811 100644 --- a/llama_stack/providers/utils/inference/openai_compat.py +++ b/llama_stack/providers/utils/inference/openai_compat.py @@ -147,6 +147,9 @@ def get_sampling_options(params: SamplingParams) -> dict: if params.repetition_penalty is not None and params.repetition_penalty != 1.0: options["repeat_penalty"] = params.repetition_penalty + if params.stop is not None: + options["stop"] = params.stop + return options diff --git a/tests/integration/inference/test_text_inference.py b/tests/integration/inference/test_text_inference.py index c9649df60..f558254e5 100644 --- a/tests/integration/inference/test_text_inference.py +++ b/tests/integration/inference/test_text_inference.py @@ -99,6 +99,33 @@ def test_text_completion_streaming(client_with_models, text_model_id, test_case) assert len(content_str) > 10 +@pytest.mark.parametrize( + "test_case", + [ + "inference:completion:stop_sequence", + ], +) +def test_text_completion_stop_sequence(client_with_models, text_model_id, inference_provider_type, test_case): + skip_if_model_doesnt_support_completion(client_with_models, text_model_id) + # This is only supported/tested for remote vLLM: https://github.com/meta-llama/llama-stack/issues/1771 + if inference_provider_type != "remote::vllm": + pytest.xfail(f"{inference_provider_type} doesn't support 'stop' parameter yet") + tc = TestCase(test_case) + + response = client_with_models.inference.completion( + content=tc["content"], + stream=True, + model_id=text_model_id, + sampling_params={ + "max_tokens": 50, + "stop": ["1963"], + }, + ) + streamed_content = [chunk.delta for chunk in response] + content_str = "".join(streamed_content).lower().strip() + assert "1963" not in content_str + + @pytest.mark.parametrize( "test_case", [ diff --git a/tests/integration/test_cases/inference/completion.json b/tests/integration/test_cases/inference/completion.json index a568ecdc9..06abbdc8b 100644 --- a/tests/integration/test_cases/inference/completion.json +++ b/tests/integration/test_cases/inference/completion.json @@ -10,6 +10,11 @@ "expected": "1963" } }, + "stop_sequence": { + "data": { + "content": "Return the exact same sentence and don't add additional words): Michael Jordan was born in the year of 1963" + } + }, "streaming": { "data": { "content": "Roses are red," From ba14552a32f3a6cb49714234e2cd8a3258168891 Mon Sep 17 00:00:00 2001 From: Daniele Martinoli <86618610+dmartinol@users.noreply.github.com> Date: Tue, 25 Mar 2025 15:04:47 +0100 Subject: [PATCH 03/45] fix: Misleading code in Llama Stack Benchmark Evals notebook (#1774) # What does this PR do? Closes #1773 Signed-off-by: Daniele Martinoli --- docs/notebooks/Llama_Stack_Benchmark_Evals.ipynb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/notebooks/Llama_Stack_Benchmark_Evals.ipynb b/docs/notebooks/Llama_Stack_Benchmark_Evals.ipynb index 2102eec0d..5de7f715e 100644 --- a/docs/notebooks/Llama_Stack_Benchmark_Evals.ipynb +++ b/docs/notebooks/Llama_Stack_Benchmark_Evals.ipynb @@ -963,16 +963,19 @@ "\n", "client.benchmarks.register(\n", " benchmark_id=\"meta-reference::mmmu\",\n", + " # Note: we can use any value as `dataset_id` because we'll be using the `evaluate_rows` API which accepts the \n", + " # `input_rows` argument and does not fetch data from the dataset.\n", " dataset_id=f\"mmmu-{subset}-{split}\",\n", - " scoring_functions=[\"basic::regex_parser_multiple_choice_answer\"],\n", + " # Note: for the same reason as above, we can use any value as `scoring_functions`.\n", + " scoring_functions=[],\n", ")\n", "\n", - "response = client.eval.evaluate_rows_alpha(\n", + "response = client.eval.evaluate_rows(\n", " benchmark_id=\"meta-reference::mmmu\",\n", " input_rows=eval_rows,\n", + " # Note: Here we define the actual scoring functions.\n", " scoring_functions=[\"basic::regex_parser_multiple_choice_answer\"],\n", " benchmark_config={\n", - " \"type\": \"benchmark\",\n", " \"eval_candidate\": {\n", " \"type\": \"model\",\n", " \"model\": \"meta-llama/Llama-3.2-90B-Vision-Instruct\",\n", @@ -1139,12 +1142,11 @@ " scoring_functions=[\"llm-as-judge::405b-simpleqa\"],\n", ")\n", "\n", - "response = client.eval.evaluate_rows_alpha(\n", + "response = client.eval.evaluate_rows(\n", " benchmark_id=\"meta-reference::simpleqa\",\n", " input_rows=eval_rows.data,\n", " scoring_functions=[\"llm-as-judge::405b-simpleqa\"],\n", " benchmark_config={\n", - " \"type\": \"benchmark\",\n", " \"eval_candidate\": {\n", " \"type\": \"model\",\n", " \"model\": \"meta-llama/Llama-3.2-90B-Vision-Instruct\",\n", @@ -1288,12 +1290,11 @@ " \"enable_session_persistence\": False,\n", "}\n", "\n", - "response = client.eval.evaluate_rows_alpha(\n", + "response = client.eval.evaluate_rows(\n", " benchmark_id=\"meta-reference::simpleqa\",\n", " input_rows=eval_rows.data,\n", " scoring_functions=[\"llm-as-judge::405b-simpleqa\"],\n", " benchmark_config={\n", - " \"type\": \"benchmark\",\n", " \"eval_candidate\": {\n", " \"type\": \"agent\",\n", " \"config\": agent_config,\n", From 1a73f8305b513b0880c7903d3458b4f89e45f3e3 Mon Sep 17 00:00:00 2001 From: Rashmi Pawar <168514198+raspawar@users.noreply.github.com> Date: Tue, 25 Mar 2025 23:31:10 +0530 Subject: [PATCH 04/45] feat: Add nemo customizer (#1448) # What does this PR do? This PR adds support for NVIDIA's NeMo Customizer API to the Llama Stack post-training module. The integration enables users to fine-tune models using NVIDIA's cloud-based customization service through a consistent Llama Stack interface. [//]: # (If resolving an issue, uncomment and update the line below) [//]: # (Closes #[issue-number]) ## Test Plan [Describe the tests you ran to verify your changes with result summaries. *Provide clear instructions so the plan can be easily re-executed.*] Yet to be done Things pending under this PR: - [x] Integration of fine-tuned model(new checkpoint) for inference with nvidia llm distribution - [x] distribution integration of API - [x] Add test cases for customizer(In Progress) - [x] Documentation ``` LLAMA_STACK_BASE_URL=http://localhost:5002 pytest -v tests/client-sdk/post_training/test_supervised_fine_tuning.py ============================================================================================================================================================================ test session starts ============================================================================================================================================================================= platform linux -- Python 3.10.0, pytest-8.3.4, pluggy-1.5.0 -- /home/ubuntu/llama-stack/.venv/bin/python cachedir: .pytest_cache metadata: {'Python': '3.10.0', 'Platform': 'Linux-6.8.0-1021-gcp-x86_64-with-glibc2.35', 'Packages': {'pytest': '8.3.4', 'pluggy': '1.5.0'}, 'Plugins': {'nbval': '0.11.0', 'metadata': '3.1.1', 'anyio': '4.8.0', 'html': '4.1.1', 'asyncio': '0.25.3'}} rootdir: /home/ubuntu/llama-stack configfile: pyproject.toml plugins: nbval-0.11.0, metadata-3.1.1, anyio-4.8.0, html-4.1.1, asyncio-0.25.3 asyncio: mode=strict, asyncio_default_fixture_loop_scope=None collected 2 items tests/client-sdk/post_training/test_supervised_fine_tuning.py::test_post_training_provider_registration[txt=8B] PASSED [ 50%] tests/client-sdk/post_training/test_supervised_fine_tuning.py::test_list_training_jobs[txt=8B] PASSED [100%] ======================================================================================================================================================================== 2 passed, 1 warning in 0.10s ======================================================================================================================================================================== ``` cc: @mattf @dglogo @sumitb --------- Co-authored-by: Ubuntu --- distributions/dependencies.json | 1 + docs/_static/llama-stack-spec.html | 6 +- docs/_static/llama-stack-spec.yaml | 2 + .../remote_hosted_distro/nvidia.md | 7 + llama_stack/apis/common/job_types.py | 1 + .../providers/registry/post_training.py | 11 +- .../remote/inference/nvidia/nvidia.py | 8 +- .../remote/post_training/__init__.py | 5 + .../remote/post_training/nvidia/README.md | 138 ++++++ .../remote/post_training/nvidia/__init__.py | 23 + .../remote/post_training/nvidia/config.py | 113 +++++ .../remote/post_training/nvidia/models.py | 24 + .../post_training/nvidia/post_training.py | 439 ++++++++++++++++++ .../remote/post_training/nvidia/utils.py | 63 +++ llama_stack/templates/nvidia/build.yaml | 2 + llama_stack/templates/nvidia/nvidia.py | 26 ++ .../templates/nvidia/run-with-safety.yaml | 9 + llama_stack/templates/nvidia/run.yaml | 9 + pyproject.toml | 5 +- tests/client-sdk/post_training/__init__.py | 5 + .../test_supervied_fine_tuning.py | 60 +++ tests/unit/providers/nvidia/__init__.py | 5 + tests/unit/providers/nvidia/conftest.py | 45 ++ .../unit/providers/nvidia/test_parameters.py | 271 +++++++++++ .../nvidia/test_supervised_fine_tuning.py | 295 ++++++++++++ uv.lock | 6 + 26 files changed, 1571 insertions(+), 8 deletions(-) create mode 100644 llama_stack/providers/remote/post_training/__init__.py create mode 100644 llama_stack/providers/remote/post_training/nvidia/README.md create mode 100644 llama_stack/providers/remote/post_training/nvidia/__init__.py create mode 100644 llama_stack/providers/remote/post_training/nvidia/config.py create mode 100644 llama_stack/providers/remote/post_training/nvidia/models.py create mode 100644 llama_stack/providers/remote/post_training/nvidia/post_training.py create mode 100644 llama_stack/providers/remote/post_training/nvidia/utils.py create mode 100644 tests/client-sdk/post_training/__init__.py create mode 100644 tests/client-sdk/post_training/test_supervied_fine_tuning.py create mode 100644 tests/unit/providers/nvidia/__init__.py create mode 100644 tests/unit/providers/nvidia/conftest.py create mode 100644 tests/unit/providers/nvidia/test_parameters.py create mode 100644 tests/unit/providers/nvidia/test_supervised_fine_tuning.py diff --git a/distributions/dependencies.json b/distributions/dependencies.json index da0de2820..931240d37 100644 --- a/distributions/dependencies.json +++ b/distributions/dependencies.json @@ -433,6 +433,7 @@ "zmq" ], "nvidia": [ + "aiohttp", "aiosqlite", "blobfile", "chardet", diff --git a/docs/_static/llama-stack-spec.html b/docs/_static/llama-stack-spec.html index 64b06e901..7b1b6a0b6 100644 --- a/docs/_static/llama-stack-spec.html +++ b/docs/_static/llama-stack-spec.html @@ -7671,7 +7671,8 @@ "completed", "in_progress", "failed", - "scheduled" + "scheduled", + "cancelled" ], "title": "JobStatus" }, @@ -8135,7 +8136,8 @@ "completed", "in_progress", "failed", - "scheduled" + "scheduled", + "cancelled" ], "title": "JobStatus" } diff --git a/docs/_static/llama-stack-spec.yaml b/docs/_static/llama-stack-spec.yaml index 78de9afef..a815931de 100644 --- a/docs/_static/llama-stack-spec.yaml +++ b/docs/_static/llama-stack-spec.yaml @@ -5306,6 +5306,7 @@ components: - in_progress - failed - scheduled + - cancelled title: JobStatus scheduled_at: type: string @@ -5583,6 +5584,7 @@ components: - in_progress - failed - scheduled + - cancelled title: JobStatus additionalProperties: false required: diff --git a/docs/source/distributions/remote_hosted_distro/nvidia.md b/docs/source/distributions/remote_hosted_distro/nvidia.md index 0db878943..58731392d 100644 --- a/docs/source/distributions/remote_hosted_distro/nvidia.md +++ b/docs/source/distributions/remote_hosted_distro/nvidia.md @@ -9,6 +9,7 @@ The `llamastack/distribution-nvidia` distribution consists of the following prov | datasetio | `inline::localfs` | | eval | `inline::meta-reference` | | inference | `remote::nvidia` | +| post_training | `remote::nvidia` | | safety | `remote::nvidia` | | scoring | `inline::basic` | | telemetry | `inline::meta-reference` | @@ -21,6 +22,12 @@ The `llamastack/distribution-nvidia` distribution consists of the following prov The following environment variables can be configured: - `NVIDIA_API_KEY`: NVIDIA API Key (default: ``) +- `NVIDIA_USER_ID`: NVIDIA User ID (default: `llama-stack-user`) +- `NVIDIA_DATASET_NAMESPACE`: NVIDIA Dataset Namespace (default: `default`) +- `NVIDIA_ACCESS_POLICIES`: NVIDIA Access Policies (default: `{}`) +- `NVIDIA_PROJECT_ID`: NVIDIA Project ID (default: `test-project`) +- `NVIDIA_CUSTOMIZER_URL`: NVIDIA Customizer URL (default: `https://customizer.api.nvidia.com`) +- `NVIDIA_OUTPUT_MODEL_DIR`: NVIDIA Output Model Directory (default: `test-example-model@v1`) - `GUARDRAILS_SERVICE_URL`: URL for the NeMo Guardrails Service (default: `http://0.0.0.0:7331`) - `INFERENCE_MODEL`: Inference model (default: `Llama3.1-8B-Instruct`) - `SAFETY_MODEL`: Name of the model to use for safety (default: `meta/llama-3.1-8b-instruct`) diff --git a/llama_stack/apis/common/job_types.py b/llama_stack/apis/common/job_types.py index 9acecc154..ca6bcaf63 100644 --- a/llama_stack/apis/common/job_types.py +++ b/llama_stack/apis/common/job_types.py @@ -15,6 +15,7 @@ class JobStatus(Enum): in_progress = "in_progress" failed = "failed" scheduled = "scheduled" + cancelled = "cancelled" @json_schema_type diff --git a/llama_stack/providers/registry/post_training.py b/llama_stack/providers/registry/post_training.py index 3bcda6508..4d10fcf3b 100644 --- a/llama_stack/providers/registry/post_training.py +++ b/llama_stack/providers/registry/post_training.py @@ -6,7 +6,7 @@ from typing import List -from llama_stack.providers.datatypes import Api, InlineProviderSpec, ProviderSpec +from llama_stack.providers.datatypes import AdapterSpec, Api, InlineProviderSpec, ProviderSpec, remote_provider_spec def available_providers() -> List[ProviderSpec]: @@ -22,4 +22,13 @@ def available_providers() -> List[ProviderSpec]: Api.datasets, ], ), + remote_provider_spec( + api=Api.post_training, + adapter=AdapterSpec( + adapter_type="nvidia", + pip_packages=["requests", "aiohttp"], + module="llama_stack.providers.remote.post_training.nvidia", + config_class="llama_stack.providers.remote.post_training.nvidia.NvidiaPostTrainingConfig", + ), + ), ] diff --git a/llama_stack/providers/remote/inference/nvidia/nvidia.py b/llama_stack/providers/remote/inference/nvidia/nvidia.py index 69e6335c6..51c8c6a79 100644 --- a/llama_stack/providers/remote/inference/nvidia/nvidia.py +++ b/llama_stack/providers/remote/inference/nvidia/nvidia.py @@ -55,7 +55,7 @@ from .openai_utils import ( convert_openai_completion_choice, convert_openai_completion_stream, ) -from .utils import _is_nvidia_hosted, check_health +from .utils import _is_nvidia_hosted logger = logging.getLogger(__name__) @@ -134,7 +134,9 @@ class NVIDIAInferenceAdapter(Inference, ModelRegistryHelper): if content_has_media(content): raise NotImplementedError("Media is not supported") - await check_health(self._config) # this raises errors + # ToDo: check health of NeMo endpoints and enable this + # removing this health check as NeMo customizer endpoint health check is returning 404 + # await check_health(self._config) # this raises errors provider_model_id = self.get_provider_model_id(model_id) request = convert_completion_request( @@ -236,7 +238,7 @@ class NVIDIAInferenceAdapter(Inference, ModelRegistryHelper): if tool_prompt_format: warnings.warn("tool_prompt_format is not supported by NVIDIA NIM, ignoring", stacklevel=2) - await check_health(self._config) # this raises errors + # await check_health(self._config) # this raises errors provider_model_id = self.get_provider_model_id(model_id) request = await convert_chat_completion_request( diff --git a/llama_stack/providers/remote/post_training/__init__.py b/llama_stack/providers/remote/post_training/__init__.py new file mode 100644 index 000000000..756f351d8 --- /dev/null +++ b/llama_stack/providers/remote/post_training/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. diff --git a/llama_stack/providers/remote/post_training/nvidia/README.md b/llama_stack/providers/remote/post_training/nvidia/README.md new file mode 100644 index 000000000..230587d66 --- /dev/null +++ b/llama_stack/providers/remote/post_training/nvidia/README.md @@ -0,0 +1,138 @@ +# NVIDIA Post-Training Provider for LlamaStack + +This provider enables fine-tuning of LLMs using NVIDIA's NeMo Customizer service. + +## Features + +- Supervised fine-tuning of Llama models +- LoRA fine-tuning support +- Job management and status tracking + +## Getting Started + +### Prerequisites + +- LlamaStack with NVIDIA configuration +- Access to Hosted NVIDIA NeMo Customizer service +- Dataset registered in the Hosted NVIDIA NeMo Customizer service +- Base model downloaded and available in the Hosted NVIDIA NeMo Customizer service + +### Setup + +Build the NVIDIA environment: + +```bash +llama stack build --template nvidia --image-type conda +``` + +### Basic Usage using the LlamaStack Python Client + +### Create Customization Job + +#### Initialize the client + +```python +import os + +os.environ["NVIDIA_API_KEY"] = "your-api-key" +os.environ["NVIDIA_CUSTOMIZER_URL"] = "http://nemo.test" +os.environ["NVIDIA_USER_ID"] = "llama-stack-user" +os.environ["NVIDIA_DATASET_NAMESPACE"] = "default" +os.environ["NVIDIA_PROJECT_ID"] = "test-project" +os.environ["NVIDIA_OUTPUT_MODEL_DIR"] = "test-example-model@v1" + +from llama_stack.distribution.library_client import LlamaStackAsLibraryClient + +client = LlamaStackAsLibraryClient("nvidia") +client.initialize() +``` + +#### Configure fine-tuning parameters + +```python +from llama_stack_client.types.post_training_supervised_fine_tune_params import ( + TrainingConfig, + TrainingConfigDataConfig, + TrainingConfigOptimizerConfig, +) +from llama_stack_client.types.algorithm_config_param import LoraFinetuningConfig +``` + +#### Set up LoRA configuration + +```python +algorithm_config = LoraFinetuningConfig(type="LoRA", adapter_dim=16) +``` + +#### Configure training data + +```python +data_config = TrainingConfigDataConfig( + dataset_id="your-dataset-id", # Use client.datasets.list() to see available datasets + batch_size=16, +) +``` + +#### Configure optimizer + +```python +optimizer_config = TrainingConfigOptimizerConfig( + lr=0.0001, +) +``` + +#### Set up training configuration + +```python +training_config = TrainingConfig( + n_epochs=2, + data_config=data_config, + optimizer_config=optimizer_config, +) +``` + +#### Start fine-tuning job + +```python +training_job = client.post_training.supervised_fine_tune( + job_uuid="unique-job-id", + model="meta-llama/Llama-3.1-8B-Instruct", + checkpoint_dir="", + algorithm_config=algorithm_config, + training_config=training_config, + logger_config={}, + hyperparam_search_config={}, +) +``` + +### List all jobs + +```python +jobs = client.post_training.job.list() +``` + +### Check job status + +```python +job_status = client.post_training.job.status(job_uuid="your-job-id") +``` + +### Cancel a job + +```python +client.post_training.job.cancel(job_uuid="your-job-id") +``` + +### Inference with the fine-tuned model + +```python +response = client.inference.completion( + content="Complete the sentence using one word: Roses are red, violets are ", + stream=False, + model_id="test-example-model@v1", + sampling_params={ + "max_tokens": 50, + }, +) +print(response.content) +``` diff --git a/llama_stack/providers/remote/post_training/nvidia/__init__.py b/llama_stack/providers/remote/post_training/nvidia/__init__.py new file mode 100644 index 000000000..17c203057 --- /dev/null +++ b/llama_stack/providers/remote/post_training/nvidia/__init__.py @@ -0,0 +1,23 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from .config import NvidiaPostTrainingConfig + + +async def get_adapter_impl( + config: NvidiaPostTrainingConfig, + _deps, +): + from .post_training import NvidiaPostTrainingAdapter + + if not isinstance(config, NvidiaPostTrainingConfig): + raise RuntimeError(f"Unexpected config type: {type(config)}") + + impl = NvidiaPostTrainingAdapter(config) + return impl + + +__all__ = ["get_adapter_impl", "NvidiaPostTrainingAdapter"] diff --git a/llama_stack/providers/remote/post_training/nvidia/config.py b/llama_stack/providers/remote/post_training/nvidia/config.py new file mode 100644 index 000000000..7b42c8bb0 --- /dev/null +++ b/llama_stack/providers/remote/post_training/nvidia/config.py @@ -0,0 +1,113 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import os +from typing import Any, Dict, Optional + +from pydantic import BaseModel, Field + +# TODO: add default values for all fields + + +class NvidiaPostTrainingConfig(BaseModel): + """Configuration for NVIDIA Post Training implementation.""" + + api_key: Optional[str] = Field( + default_factory=lambda: os.getenv("NVIDIA_API_KEY"), + description="The NVIDIA API key.", + ) + + dataset_namespace: Optional[str] = Field( + default_factory=lambda: os.getenv("NVIDIA_DATASET_NAMESPACE", "default"), + description="The NVIDIA dataset namespace.", + ) + + project_id: Optional[str] = Field( + default_factory=lambda: os.getenv("NVIDIA_PROJECT_ID", "test-example-model@v1"), + description="The NVIDIA project ID.", + ) + + # ToDO: validate this, add default value + customizer_url: Optional[str] = Field( + default_factory=lambda: os.getenv("NVIDIA_CUSTOMIZER_URL"), + description="Base URL for the NeMo Customizer API", + ) + + timeout: int = Field( + default=300, + description="Timeout for the NVIDIA Post Training API", + ) + + max_retries: int = Field( + default=3, + description="Maximum number of retries for the NVIDIA Post Training API", + ) + + # ToDo: validate this + output_model_dir: str = Field( + default_factory=lambda: os.getenv("NVIDIA_OUTPUT_MODEL_DIR", "test-example-model@v1"), + description="Directory to save the output model", + ) + + @classmethod + def sample_run_config(cls, **kwargs) -> Dict[str, Any]: + return { + "api_key": "${env.NVIDIA_API_KEY:}", + "dataset_namespace": "${env.NVIDIA_DATASET_NAMESPACE:default}", + "project_id": "${env.NVIDIA_PROJECT_ID:test-project}", + "customizer_url": "${env.NVIDIA_CUSTOMIZER_URL:http://nemo.test}", + } + + +class SFTLoRADefaultConfig(BaseModel): + """NVIDIA-specific training configuration with default values.""" + + # ToDo: split into SFT and LoRA configs?? + + # General training parameters + n_epochs: int = 50 + + # NeMo customizer specific parameters + log_every_n_steps: Optional[int] = None + val_check_interval: float = 0.25 + sequence_packing_enabled: bool = False + weight_decay: float = 0.01 + lr: float = 0.0001 + + # SFT specific parameters + hidden_dropout: Optional[float] = None + attention_dropout: Optional[float] = None + ffn_dropout: Optional[float] = None + + # LoRA default parameters + lora_adapter_dim: int = 8 + lora_adapter_dropout: Optional[float] = None + lora_alpha: int = 16 + + # Data config + batch_size: int = 8 + + @classmethod + def sample_config(cls) -> Dict[str, Any]: + """Return a sample configuration for NVIDIA training.""" + return { + "n_epochs": 50, + "log_every_n_steps": 10, + "val_check_interval": 0.25, + "sequence_packing_enabled": False, + "weight_decay": 0.01, + "hidden_dropout": 0.1, + "attention_dropout": 0.1, + "lora_adapter_dim": 8, + "lora_alpha": 16, + "data_config": { + "dataset_id": "default", + "batch_size": 8, + }, + "optimizer_config": { + "lr": 0.0001, + }, + } diff --git a/llama_stack/providers/remote/post_training/nvidia/models.py b/llama_stack/providers/remote/post_training/nvidia/models.py new file mode 100644 index 000000000..04a9af38c --- /dev/null +++ b/llama_stack/providers/remote/post_training/nvidia/models.py @@ -0,0 +1,24 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from typing import List + +from llama_stack.models.llama.datatypes import CoreModelId +from llama_stack.providers.utils.inference.model_registry import ( + ProviderModelEntry, + build_hf_repo_model_entry, +) + +_MODEL_ENTRIES = [ + build_hf_repo_model_entry( + "meta/llama-3.1-8b-instruct", + CoreModelId.llama3_1_8b_instruct.value, + ) +] + + +def get_model_entries() -> List[ProviderModelEntry]: + return _MODEL_ENTRIES diff --git a/llama_stack/providers/remote/post_training/nvidia/post_training.py b/llama_stack/providers/remote/post_training/nvidia/post_training.py new file mode 100644 index 000000000..bacfdba0b --- /dev/null +++ b/llama_stack/providers/remote/post_training/nvidia/post_training.py @@ -0,0 +1,439 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. +import warnings +from datetime import datetime +from typing import Any, Dict, List, Literal, Optional + +import aiohttp +from pydantic import BaseModel, ConfigDict + +from llama_stack.apis.post_training import ( + AlgorithmConfig, + DPOAlignmentConfig, + JobStatus, + PostTrainingJob, + PostTrainingJobArtifactsResponse, + PostTrainingJobStatusResponse, + TrainingConfig, +) +from llama_stack.providers.remote.post_training.nvidia.config import NvidiaPostTrainingConfig +from llama_stack.providers.remote.post_training.nvidia.utils import warn_unsupported_params +from llama_stack.providers.utils.inference.model_registry import ModelRegistryHelper + +from .models import _MODEL_ENTRIES + +# Map API status to JobStatus enum +STATUS_MAPPING = { + "running": "in_progress", + "completed": "completed", + "failed": "failed", + "cancelled": "cancelled", + "pending": "scheduled", +} + + +class NvidiaPostTrainingJob(PostTrainingJob): + """Parse the response from the Customizer API. + Inherits job_uuid from PostTrainingJob. + Adds status, created_at, updated_at parameters. + Passes through all other parameters from data field in the response. + """ + + model_config = ConfigDict(extra="allow") + status: JobStatus + created_at: datetime + updated_at: datetime + + +class ListNvidiaPostTrainingJobs(BaseModel): + data: List[NvidiaPostTrainingJob] + + +class NvidiaPostTrainingJobStatusResponse(PostTrainingJobStatusResponse): + model_config = ConfigDict(extra="allow") + + +class NvidiaPostTrainingAdapter(ModelRegistryHelper): + def __init__(self, config: NvidiaPostTrainingConfig): + self.config = config + self.headers = {} + if config.api_key: + self.headers["Authorization"] = f"Bearer {config.api_key}" + + self.timeout = aiohttp.ClientTimeout(total=config.timeout) + # TODO: filter by available models based on /config endpoint + ModelRegistryHelper.__init__(self, model_entries=_MODEL_ENTRIES) + self.session = aiohttp.ClientSession(headers=self.headers, timeout=self.timeout) + self.customizer_url = config.customizer_url + + if not self.customizer_url: + warnings.warn("Customizer URL is not set, using default value: http://nemo.test", stacklevel=2) + self.customizer_url = "http://nemo.test" + + async def _make_request( + self, + method: str, + path: str, + headers: Optional[Dict[str, Any]] = None, + params: Optional[Dict[str, Any]] = None, + json: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> Dict[str, Any]: + """Helper method to make HTTP requests to the Customizer API.""" + url = f"{self.customizer_url}{path}" + request_headers = self.headers.copy() + + if headers: + request_headers.update(headers) + + # Add content-type header for JSON requests + if json and "Content-Type" not in request_headers: + request_headers["Content-Type"] = "application/json" + + for _ in range(self.config.max_retries): + async with self.session.request(method, url, params=params, json=json, **kwargs) as response: + if response.status >= 400: + error_data = await response.json() + raise Exception(f"API request failed: {error_data}") + return await response.json() + + async def get_training_jobs( + self, + page: Optional[int] = 1, + page_size: Optional[int] = 10, + sort: Optional[Literal["created_at", "-created_at"]] = "created_at", + ) -> ListNvidiaPostTrainingJobs: + """Get all customization jobs. + Updated the base class return type from ListPostTrainingJobsResponse to ListNvidiaPostTrainingJobs. + + Returns a ListNvidiaPostTrainingJobs object with the following fields: + - data: List[NvidiaPostTrainingJob] - List of NvidiaPostTrainingJob objects + + ToDo: Support for schema input for filtering. + """ + params = {"page": page, "page_size": page_size, "sort": sort} + + response = await self._make_request("GET", "/v1/customization/jobs", params=params) + + jobs = [] + for job in response.get("data", []): + job_id = job.pop("id") + job_status = job.pop("status", "unknown").lower() + mapped_status = STATUS_MAPPING.get(job_status, "unknown") + + # Convert string timestamps to datetime objects + created_at = ( + datetime.fromisoformat(job.pop("created_at")) + if "created_at" in job + else datetime.now(tz=datetime.timezone.utc) + ) + updated_at = ( + datetime.fromisoformat(job.pop("updated_at")) + if "updated_at" in job + else datetime.now(tz=datetime.timezone.utc) + ) + + # Create NvidiaPostTrainingJob instance + jobs.append( + NvidiaPostTrainingJob( + job_uuid=job_id, + status=JobStatus(mapped_status), + created_at=created_at, + updated_at=updated_at, + **job, + ) + ) + + return ListNvidiaPostTrainingJobs(data=jobs) + + async def get_training_job_status(self, job_uuid: str) -> NvidiaPostTrainingJobStatusResponse: + """Get the status of a customization job. + Updated the base class return type from PostTrainingJobResponse to NvidiaPostTrainingJob. + + Returns a NvidiaPostTrainingJob object with the following fields: + - job_uuid: str - Unique identifier for the job + - status: JobStatus - Current status of the job (in_progress, completed, failed, cancelled, scheduled) + - created_at: datetime - The time when the job was created + - updated_at: datetime - The last time the job status was updated + + Additional fields that may be included: + - steps_completed: Optional[int] - Number of training steps completed + - epochs_completed: Optional[int] - Number of epochs completed + - percentage_done: Optional[float] - Percentage of training completed (0-100) + - best_epoch: Optional[int] - The epoch with the best performance + - train_loss: Optional[float] - Training loss of the best checkpoint + - val_loss: Optional[float] - Validation loss of the best checkpoint + - metrics: Optional[Dict] - Additional training metrics + - status_logs: Optional[List] - Detailed logs of status changes + """ + response = await self._make_request( + "GET", + f"/v1/customization/jobs/{job_uuid}/status", + params={"job_id": job_uuid}, + ) + + api_status = response.pop("status").lower() + mapped_status = STATUS_MAPPING.get(api_status, "unknown") + + return NvidiaPostTrainingJobStatusResponse( + status=JobStatus(mapped_status), + job_uuid=job_uuid, + started_at=datetime.fromisoformat(response.pop("created_at")), + updated_at=datetime.fromisoformat(response.pop("updated_at")), + **response, + ) + + async def cancel_training_job(self, job_uuid: str) -> None: + await self._make_request( + method="POST", path=f"/v1/customization/jobs/{job_uuid}/cancel", params={"job_id": job_uuid} + ) + + async def get_training_job_artifacts(self, job_uuid: str) -> PostTrainingJobArtifactsResponse: + raise NotImplementedError("Job artifacts are not implemented yet") + + async def get_post_training_artifacts(self, job_uuid: str) -> PostTrainingJobArtifactsResponse: + raise NotImplementedError("Job artifacts are not implemented yet") + + async def supervised_fine_tune( + self, + job_uuid: str, + training_config: Dict[str, Any], + hyperparam_search_config: Dict[str, Any], + logger_config: Dict[str, Any], + model: str, + checkpoint_dir: Optional[str], + algorithm_config: Optional[AlgorithmConfig] = None, + extra_json: Optional[Dict[str, Any]] = None, + params: Optional[Dict[str, Any]] = None, + headers: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> NvidiaPostTrainingJob: + """ + Fine-tunes a model on a dataset. + Currently only supports Lora finetuning for standlone docker container. + Assumptions: + - nemo microservice is running and endpoint is set in config.customizer_url + - dataset is registered separately in nemo datastore + - model checkpoint is downloaded as per nemo customizer requirements + + Parameters: + training_config: TrainingConfig - Configuration for training + model: str - Model identifier + algorithm_config: Optional[AlgorithmConfig] - Algorithm-specific configuration + checkpoint_dir: Optional[str] - Directory containing model checkpoints, ignored atm + job_uuid: str - Unique identifier for the job, ignored atm + hyperparam_search_config: Dict[str, Any] - Configuration for hyperparameter search, ignored atm + logger_config: Dict[str, Any] - Configuration for logging, ignored atm + + Environment Variables: + - NVIDIA_API_KEY: str - API key for the NVIDIA API + Default: None + - NVIDIA_DATASET_NAMESPACE: str - Namespace of the dataset + Default: "default" + - NVIDIA_CUSTOMIZER_URL: str - URL of the NeMo Customizer API + Default: "http://nemo.test" + - NVIDIA_PROJECT_ID: str - ID of the project + Default: "test-project" + - NVIDIA_OUTPUT_MODEL_DIR: str - Directory to save the output model + Default: "test-example-model@v1" + + Supported models: + - meta/llama-3.1-8b-instruct + + Supported algorithm configs: + - LoRA, SFT + + Supported Parameters: + - TrainingConfig: + - n_epochs: int - Number of epochs to train + Default: 50 + - data_config: DataConfig - Configuration for the dataset + - optimizer_config: OptimizerConfig - Configuration for the optimizer + - dtype: str - Data type for training + not supported (users are informed via warnings) + - efficiency_config: EfficiencyConfig - Configuration for efficiency + not supported + - max_steps_per_epoch: int - Maximum number of steps per epoch + Default: 1000 + ## NeMo customizer specific parameters + - log_every_n_steps: int - Log every n steps + Default: None + - val_check_interval: float - Validation check interval + Default: 0.25 + - sequence_packing_enabled: bool - Sequence packing enabled + Default: False + ## NeMo customizer specific SFT parameters + - hidden_dropout: float - Hidden dropout + Default: None (0.0-1.0) + - attention_dropout: float - Attention dropout + Default: None (0.0-1.0) + - ffn_dropout: float - FFN dropout + Default: None (0.0-1.0) + + - DataConfig: + - dataset_id: str - Dataset ID + - batch_size: int - Batch size + Default: 8 + + - OptimizerConfig: + - lr: float - Learning rate + Default: 0.0001 + ## NeMo customizer specific parameter + - weight_decay: float - Weight decay + Default: 0.01 + + - LoRA config: + ## NeMo customizer specific LoRA parameters + - adapter_dim: int - Adapter dimension + Default: 8 (supports powers of 2) + - adapter_dropout: float - Adapter dropout + Default: None (0.0-1.0) + - alpha: int - Scaling factor for the LoRA update + Default: 16 + Note: + - checkpoint_dir, hyperparam_search_config, logger_config are not supported (users are informed via warnings) + - Some parameters from TrainingConfig, DataConfig, OptimizerConfig are not supported (users are informed via warnings) + + User is informed about unsupported parameters via warnings. + """ + # Map model to nvidia model name + # ToDo: only supports llama-3.1-8b-instruct now, need to update this to support other models + nvidia_model = self.get_provider_model_id(model) + + # Check for unsupported method parameters + unsupported_method_params = [] + if checkpoint_dir: + unsupported_method_params.append(f"checkpoint_dir={checkpoint_dir}") + if hyperparam_search_config: + unsupported_method_params.append("hyperparam_search_config") + if logger_config: + unsupported_method_params.append("logger_config") + + if unsupported_method_params: + warnings.warn( + f"Parameters: {', '.join(unsupported_method_params)} are not supported and will be ignored", + stacklevel=2, + ) + + # Define all supported parameters + supported_params = { + "training_config": { + "n_epochs", + "data_config", + "optimizer_config", + "log_every_n_steps", + "val_check_interval", + "sequence_packing_enabled", + "hidden_dropout", + "attention_dropout", + "ffn_dropout", + }, + "data_config": {"dataset_id", "batch_size"}, + "optimizer_config": {"lr", "weight_decay"}, + "lora_config": {"type", "adapter_dim", "adapter_dropout", "alpha"}, + } + + # Validate all parameters at once + warn_unsupported_params(training_config, supported_params["training_config"], "TrainingConfig") + warn_unsupported_params(training_config["data_config"], supported_params["data_config"], "DataConfig") + warn_unsupported_params( + training_config["optimizer_config"], supported_params["optimizer_config"], "OptimizerConfig" + ) + + output_model = self.config.output_model_dir + + # Prepare base job configuration + job_config = { + "config": nvidia_model, + "dataset": { + "name": training_config["data_config"]["dataset_id"], + "namespace": self.config.dataset_namespace, + }, + "hyperparameters": { + "training_type": "sft", + "finetuning_type": "lora", + **{ + k: v + for k, v in { + "epochs": training_config.get("n_epochs"), + "batch_size": training_config["data_config"].get("batch_size"), + "learning_rate": training_config["optimizer_config"].get("lr"), + "weight_decay": training_config["optimizer_config"].get("weight_decay"), + "log_every_n_steps": training_config.get("log_every_n_steps"), + "val_check_interval": training_config.get("val_check_interval"), + "sequence_packing_enabled": training_config.get("sequence_packing_enabled"), + }.items() + if v is not None + }, + }, + "project": self.config.project_id, + # TODO: ignored ownership, add it later + # "ownership": {"created_by": self.config.user_id, "access_policies": self.config.access_policies}, + "output_model": output_model, + } + + # Handle SFT-specific optional parameters + job_config["hyperparameters"]["sft"] = { + k: v + for k, v in { + "ffn_dropout": training_config.get("ffn_dropout"), + "hidden_dropout": training_config.get("hidden_dropout"), + "attention_dropout": training_config.get("attention_dropout"), + }.items() + if v is not None + } + + # Remove the sft dictionary if it's empty + if not job_config["hyperparameters"]["sft"]: + job_config["hyperparameters"].pop("sft") + + # Handle LoRA-specific configuration + if algorithm_config: + if isinstance(algorithm_config, dict) and algorithm_config.get("type") == "LoRA": + warn_unsupported_params(algorithm_config, supported_params["lora_config"], "LoRA config") + job_config["hyperparameters"]["lora"] = { + k: v + for k, v in { + "adapter_dim": algorithm_config.get("adapter_dim"), + "alpha": algorithm_config.get("alpha"), + "adapter_dropout": algorithm_config.get("adapter_dropout"), + }.items() + if v is not None + } + else: + raise NotImplementedError(f"Unsupported algorithm config: {algorithm_config}") + + # Create the customization job + response = await self._make_request( + method="POST", + path="/v1/customization/jobs", + headers={"Accept": "application/json"}, + json=job_config, + ) + + job_uuid = response["id"] + response.pop("status") + created_at = datetime.fromisoformat(response.pop("created_at")) + updated_at = datetime.fromisoformat(response.pop("updated_at")) + + return NvidiaPostTrainingJob( + job_uuid=job_uuid, status=JobStatus.in_progress, created_at=created_at, updated_at=updated_at, **response + ) + + async def preference_optimize( + self, + job_uuid: str, + finetuned_model: str, + algorithm_config: DPOAlignmentConfig, + training_config: TrainingConfig, + hyperparam_search_config: Dict[str, Any], + logger_config: Dict[str, Any], + ) -> PostTrainingJob: + """Optimize a model based on preference data.""" + raise NotImplementedError("Preference optimization is not implemented yet") + + async def get_training_job_container_logs(self, job_uuid: str) -> PostTrainingJobStatusResponse: + raise NotImplementedError("Job logs are not implemented yet") diff --git a/llama_stack/providers/remote/post_training/nvidia/utils.py b/llama_stack/providers/remote/post_training/nvidia/utils.py new file mode 100644 index 000000000..ac47966af --- /dev/null +++ b/llama_stack/providers/remote/post_training/nvidia/utils.py @@ -0,0 +1,63 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import logging +import warnings +from typing import Any, Dict, Set, Tuple + +from pydantic import BaseModel + +from llama_stack.apis.post_training import TrainingConfig +from llama_stack.providers.remote.post_training.nvidia.config import SFTLoRADefaultConfig + +from .config import NvidiaPostTrainingConfig + +logger = logging.getLogger(__name__) + + +def warn_unsupported_params(config_dict: Any, supported_keys: Set[str], config_name: str) -> None: + keys = set(config_dict.__annotations__.keys()) if isinstance(config_dict, BaseModel) else config_dict.keys() + unsupported_params = [k for k in keys if k not in supported_keys] + if unsupported_params: + warnings.warn( + f"Parameters: {unsupported_params} in `{config_name}` not supported and will be ignored.", stacklevel=2 + ) + + +def validate_training_params( + training_config: Dict[str, Any], supported_keys: Set[str], config_name: str = "TrainingConfig" +) -> None: + """ + Validates training parameters against supported keys. + + Args: + training_config: Dictionary containing training configuration parameters + supported_keys: Set of supported parameter keys + config_name: Name of the configuration for warning messages + """ + sft_lora_fields = set(SFTLoRADefaultConfig.__annotations__.keys()) + training_config_fields = set(TrainingConfig.__annotations__.keys()) + + # Check for not supported parameters: + # - not in either of configs + # - in TrainingConfig but not in SFTLoRADefaultConfig + unsupported_params = [] + for key in training_config: + if isinstance(key, str) and key not in (supported_keys.union(sft_lora_fields)): + if key in (not sft_lora_fields or training_config_fields): + unsupported_params.append(key) + + if unsupported_params: + warnings.warn( + f"Parameters: {unsupported_params} in `{config_name}` are not supported and will be ignored.", stacklevel=2 + ) + + +# ToDo: implement post health checks for customizer are enabled +async def _get_health(url: str) -> Tuple[bool, bool]: ... + + +async def check_health(config: NvidiaPostTrainingConfig) -> None: ... diff --git a/llama_stack/templates/nvidia/build.yaml b/llama_stack/templates/nvidia/build.yaml index 0c788ce86..f99ff6c81 100644 --- a/llama_stack/templates/nvidia/build.yaml +++ b/llama_stack/templates/nvidia/build.yaml @@ -14,6 +14,8 @@ distribution_spec: - inline::meta-reference eval: - inline::meta-reference + post_training: + - remote::nvidia datasetio: - inline::localfs scoring: diff --git a/llama_stack/templates/nvidia/nvidia.py b/llama_stack/templates/nvidia/nvidia.py index 308c0e2a6..3b0cbe1e5 100644 --- a/llama_stack/templates/nvidia/nvidia.py +++ b/llama_stack/templates/nvidia/nvidia.py @@ -21,6 +21,7 @@ def get_distribution_template() -> DistributionTemplate: "agents": ["inline::meta-reference"], "telemetry": ["inline::meta-reference"], "eval": ["inline::meta-reference"], + "post_training": ["remote::nvidia"], "datasetio": ["inline::localfs"], "scoring": ["inline::basic"], "tool_runtime": ["inline::rag-runtime"], @@ -89,6 +90,31 @@ def get_distribution_template() -> DistributionTemplate: "", "NVIDIA API Key", ), + ## Nemo Customizer related variables + "NVIDIA_USER_ID": ( + "llama-stack-user", + "NVIDIA User ID", + ), + "NVIDIA_DATASET_NAMESPACE": ( + "default", + "NVIDIA Dataset Namespace", + ), + "NVIDIA_ACCESS_POLICIES": ( + "{}", + "NVIDIA Access Policies", + ), + "NVIDIA_PROJECT_ID": ( + "test-project", + "NVIDIA Project ID", + ), + "NVIDIA_CUSTOMIZER_URL": ( + "https://customizer.api.nvidia.com", + "NVIDIA Customizer URL", + ), + "NVIDIA_OUTPUT_MODEL_DIR": ( + "test-example-model@v1", + "NVIDIA Output Model Directory", + ), "GUARDRAILS_SERVICE_URL": ( "http://0.0.0.0:7331", "URL for the NeMo Guardrails Service", diff --git a/llama_stack/templates/nvidia/run-with-safety.yaml b/llama_stack/templates/nvidia/run-with-safety.yaml index fe6263122..d4e9e0d33 100644 --- a/llama_stack/templates/nvidia/run-with-safety.yaml +++ b/llama_stack/templates/nvidia/run-with-safety.yaml @@ -5,6 +5,7 @@ apis: - datasetio - eval - inference +- post_training - safety - scoring - telemetry @@ -58,6 +59,14 @@ providers: type: sqlite namespace: null db_path: ${env.SQLITE_STORE_DIR:~/.llama/distributions/nvidia}/meta_reference_eval.db + post_training: + - provider_id: nvidia + provider_type: remote::nvidia + config: + api_key: ${env.NVIDIA_API_KEY:} + dataset_namespace: ${env.NVIDIA_DATASET_NAMESPACE:default} + project_id: ${env.NVIDIA_PROJECT_ID:test-project} + customizer_url: ${env.NVIDIA_CUSTOMIZER_URL:http://nemo.test} datasetio: - provider_id: localfs provider_type: inline::localfs diff --git a/llama_stack/templates/nvidia/run.yaml b/llama_stack/templates/nvidia/run.yaml index 4aa00082a..9df324bfc 100644 --- a/llama_stack/templates/nvidia/run.yaml +++ b/llama_stack/templates/nvidia/run.yaml @@ -5,6 +5,7 @@ apis: - datasetio - eval - inference +- post_training - safety - scoring - telemetry @@ -53,6 +54,14 @@ providers: type: sqlite namespace: null db_path: ${env.SQLITE_STORE_DIR:~/.llama/distributions/nvidia}/meta_reference_eval.db + post_training: + - provider_id: nvidia + provider_type: remote::nvidia + config: + api_key: ${env.NVIDIA_API_KEY:} + dataset_namespace: ${env.NVIDIA_DATASET_NAMESPACE:default} + project_id: ${env.NVIDIA_PROJECT_ID:test-project} + customizer_url: ${env.NVIDIA_CUSTOMIZER_URL:http://nemo.test} datasetio: - provider_id: localfs provider_type: inline::localfs diff --git a/pyproject.toml b/pyproject.toml index f7125b724..0b34a601c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ dev = [ "ruamel.yaml", # needed for openapi generator ] # These are the dependencies required for running unit tests. -unit = ["sqlite-vec", "openai", "aiosqlite", "pypdf", "chardet", "qdrant-client"] +unit = ["sqlite-vec", "openai", "aiosqlite", "aiohttp", "pypdf", "chardet", "qdrant-client"] # These are the core dependencies required for running integration tests. They are shared across all # providers. If a provider requires additional dependencies, please add them to your environment # separately. If you are using "uv" to execute your tests, you can use the "--with" flag to specify extra @@ -64,6 +64,7 @@ unit = ["sqlite-vec", "openai", "aiosqlite", "pypdf", "chardet", "qdrant-client" test = [ "openai", "aiosqlite", + "aiohttp", "torch>=2.6.0", "torchvision>=0.21.0", "opentelemetry-sdk", @@ -130,7 +131,6 @@ select = [ "F", # Pyflakes "N", # Naming "W", # Warnings - "I", # isort "DTZ", # datetime rules ] ignore = [ @@ -262,6 +262,7 @@ exclude = [ "^llama_stack/providers/remote/tool_runtime/model_context_protocol/", "^llama_stack/providers/remote/tool_runtime/tavily_search/", "^llama_stack/providers/remote/tool_runtime/wolfram_alpha/", + "^llama_stack/providers/remote/post_training/nvidia/", "^llama_stack/providers/remote/vector_io/chroma/", "^llama_stack/providers/remote/vector_io/milvus/", "^llama_stack/providers/remote/vector_io/pgvector/", diff --git a/tests/client-sdk/post_training/__init__.py b/tests/client-sdk/post_training/__init__.py new file mode 100644 index 000000000..756f351d8 --- /dev/null +++ b/tests/client-sdk/post_training/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. diff --git a/tests/client-sdk/post_training/test_supervied_fine_tuning.py b/tests/client-sdk/post_training/test_supervied_fine_tuning.py new file mode 100644 index 000000000..232510478 --- /dev/null +++ b/tests/client-sdk/post_training/test_supervied_fine_tuning.py @@ -0,0 +1,60 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import pytest + +POST_TRAINING_PROVIDER_TYPES = ["remote::nvidia"] + + +@pytest.mark.integration +@pytest.fixture(scope="session") +def post_training_provider_available(llama_stack_client): + providers = llama_stack_client.providers.list() + post_training_providers = [p for p in providers if p.provider_type in POST_TRAINING_PROVIDER_TYPES] + return len(post_training_providers) > 0 + + +@pytest.mark.integration +def test_post_training_provider_registration(llama_stack_client, post_training_provider_available): + """Check if post_training is in the api list. + This is a sanity check to ensure the provider is registered.""" + if not post_training_provider_available: + pytest.skip("post training provider not available") + + providers = llama_stack_client.providers.list() + post_training_providers = [p for p in providers if p.provider_type in POST_TRAINING_PROVIDER_TYPES] + assert len(post_training_providers) > 0 + + +@pytest.mark.integration +def test_get_training_jobs(llama_stack_client, post_training_provider_available): + """Test listing all training jobs.""" + if not post_training_provider_available: + pytest.skip("post training provider not available") + + jobs = llama_stack_client.post_training.get_training_jobs() + assert isinstance(jobs, dict) + assert "data" in jobs + assert isinstance(jobs["data"], list) + + +@pytest.mark.integration +def test_get_training_job_status(llama_stack_client, post_training_provider_available): + """Test getting status of a specific training job.""" + if not post_training_provider_available: + pytest.skip("post training provider not available") + + jobs = llama_stack_client.post_training.get_training_jobs() + if not jobs["data"]: + pytest.skip("No training jobs available to check status") + + job_uuid = jobs["data"][0]["job_uuid"] + job_status = llama_stack_client.post_training.get_training_job_status(job_uuid=job_uuid) + + assert job_status is not None + assert "job_uuid" in job_status + assert "status" in job_status + assert job_status["job_uuid"] == job_uuid diff --git a/tests/unit/providers/nvidia/__init__.py b/tests/unit/providers/nvidia/__init__.py new file mode 100644 index 000000000..756f351d8 --- /dev/null +++ b/tests/unit/providers/nvidia/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. diff --git a/tests/unit/providers/nvidia/conftest.py b/tests/unit/providers/nvidia/conftest.py new file mode 100644 index 000000000..1c4a1d145 --- /dev/null +++ b/tests/unit/providers/nvidia/conftest.py @@ -0,0 +1,45 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import asyncio +import pytest +from unittest.mock import AsyncMock, MagicMock, patch + +mock_session = MagicMock() +mock_session.closed = False +mock_session.close = AsyncMock() +mock_session.__aenter__ = AsyncMock(return_value=mock_session) +mock_session.__aexit__ = AsyncMock() + + +@pytest.fixture(scope="session", autouse=True) +def patch_aiohttp_session(): + with patch("aiohttp.ClientSession", return_value=mock_session): + yield + + +@pytest.fixture +def event_loop(): + """Create and provide a new event loop for each test.""" + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + yield loop + loop.close() + + +@pytest.fixture +def run_async(): + """Fixture to run async functions in tests.""" + + def _run_async(coro): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + return loop.run_until_complete(coro) + finally: + loop.close() + + return _run_async diff --git a/tests/unit/providers/nvidia/test_parameters.py b/tests/unit/providers/nvidia/test_parameters.py new file mode 100644 index 000000000..bf579fbfb --- /dev/null +++ b/tests/unit/providers/nvidia/test_parameters.py @@ -0,0 +1,271 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import os +import unittest +import warnings +from unittest.mock import patch +import pytest + +from llama_stack_client.types.algorithm_config_param import LoraFinetuningConfig +from llama_stack_client.types.post_training_supervised_fine_tune_params import ( + TrainingConfig, + TrainingConfigDataConfig, + TrainingConfigOptimizerConfig, + TrainingConfigEfficiencyConfig, +) +from llama_stack.providers.remote.post_training.nvidia.post_training import ( + NvidiaPostTrainingAdapter, + NvidiaPostTrainingConfig, +) + + +class TestNvidiaParameters(unittest.TestCase): + def setUp(self): + os.environ["NVIDIA_BASE_URL"] = "http://nemo.test" + os.environ["NVIDIA_CUSTOMIZER_URL"] = "http://nemo.test" + + config = NvidiaPostTrainingConfig( + base_url=os.environ["NVIDIA_BASE_URL"], customizer_url=os.environ["NVIDIA_CUSTOMIZER_URL"], api_key=None + ) + self.adapter = NvidiaPostTrainingAdapter(config) + + self.make_request_patcher = patch( + "llama_stack.providers.remote.post_training.nvidia.post_training.NvidiaPostTrainingAdapter._make_request" + ) + self.mock_make_request = self.make_request_patcher.start() + self.mock_make_request.return_value = { + "id": "job-123", + "status": "created", + "created_at": "2025-03-04T13:07:47.543605", + "updated_at": "2025-03-04T13:07:47.543605", + } + + def tearDown(self): + self.make_request_patcher.stop() + + def _assert_request_params(self, expected_json): + """Helper method to verify parameters in the request JSON.""" + call_args = self.mock_make_request.call_args + actual_json = call_args[1]["json"] + + for key, value in expected_json.items(): + if isinstance(value, dict): + for nested_key, nested_value in value.items(): + assert actual_json[key][nested_key] == nested_value + else: + assert actual_json[key] == value + + @pytest.fixture(autouse=True) + def inject_fixtures(self, run_async): + self.run_async = run_async + + def test_customizer_parameters_passed(self): + """Test scenario 1: When an optional parameter is passed and value is correctly set.""" + custom_adapter_dim = 32 # Different from default of 8 + algorithm_config = LoraFinetuningConfig( + type="LoRA", + adapter_dim=custom_adapter_dim, + adapter_dropout=0.2, + apply_lora_to_mlp=True, + apply_lora_to_output=True, + alpha=16, + rank=16, + lora_attn_modules=["q_proj", "k_proj", "v_proj", "o_proj"], + ) + + data_config = TrainingConfigDataConfig(dataset_id="test-dataset", batch_size=16) + optimizer_config = TrainingConfigOptimizerConfig(lr=0.0002) + training_config = TrainingConfig( + n_epochs=3, + data_config=data_config, + optimizer_config=optimizer_config, + ) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + + self.run_async( + self.adapter.supervised_fine_tune( + job_uuid="test-job", + model="meta-llama/Llama-3.1-8B-Instruct", + checkpoint_dir="", + algorithm_config=algorithm_config, + training_config=training_config, + logger_config={}, + hyperparam_search_config={}, + ) + ) + + warning_texts = [str(warning.message) for warning in w] + + fields = [ + "apply_lora_to_output", + "lora_attn_modules", + "apply_lora_to_mlp", + ] + for field in fields: + assert any(field in text for text in warning_texts) + + self._assert_request_params( + { + "hyperparameters": { + "lora": {"adapter_dim": custom_adapter_dim, "adapter_dropout": 0.2, "alpha": 16}, + "epochs": 3, + "learning_rate": 0.0002, + "batch_size": 16, + } + } + ) + + def test_required_parameters_passed(self): + """Test scenario 2: When required parameters are passed.""" + required_model = "meta-llama/Llama-3.1-8B-Instruct" + required_dataset_id = "required-dataset" + required_job_uuid = "required-job" + + algorithm_config = LoraFinetuningConfig( + type="LoRA", + adapter_dim=16, + adapter_dropout=0.1, + apply_lora_to_mlp=True, + apply_lora_to_output=True, + alpha=16, + rank=16, + lora_attn_modules=["q_proj", "k_proj", "v_proj", "o_proj"], + ) + + data_config = TrainingConfigDataConfig( + dataset_id=required_dataset_id, # Required parameter + batch_size=8, + ) + + optimizer_config = TrainingConfigOptimizerConfig(lr=0.0001) + + training_config = TrainingConfig( + n_epochs=1, + data_config=data_config, + optimizer_config=optimizer_config, + ) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + + self.run_async( + self.adapter.supervised_fine_tune( + job_uuid=required_job_uuid, # Required parameter + model=required_model, # Required parameter + checkpoint_dir="", + algorithm_config=algorithm_config, + training_config=training_config, + logger_config={}, + hyperparam_search_config={}, + ) + ) + + warning_texts = [str(warning.message) for warning in w] + + fields = [ + "rank", + "apply_lora_to_output", + "lora_attn_modules", + "apply_lora_to_mlp", + ] + for field in fields: + assert any(field in text for text in warning_texts) + + self.mock_make_request.assert_called_once() + call_args = self.mock_make_request.call_args + + assert call_args[1]["json"]["config"] == "meta/llama-3.1-8b-instruct" + assert call_args[1]["json"]["dataset"]["name"] == required_dataset_id + + def test_unsupported_parameters_warning(self): + """Test that warnings are raised for unsupported parameters.""" + data_config = TrainingConfigDataConfig( + dataset_id="test-dataset", + batch_size=8, + # Unsupported parameters + shuffle=True, + data_format="instruct", + validation_dataset_id="val-dataset", + ) + + optimizer_config = TrainingConfigOptimizerConfig( + lr=0.0001, + weight_decay=0.01, + # Unsupported parameters + optimizer_type="adam", + num_warmup_steps=100, + ) + + efficiency_config = TrainingConfigEfficiencyConfig( + enable_activation_checkpointing=True # Unsupported parameter + ) + + training_config = TrainingConfig( + n_epochs=1, + data_config=data_config, + optimizer_config=optimizer_config, + # Unsupported parameters + efficiency_config=efficiency_config, + max_steps_per_epoch=1000, + gradient_accumulation_steps=4, + max_validation_steps=100, + dtype="bf16", + ) + + # Capture warnings + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + + self.run_async( + self.adapter.supervised_fine_tune( + job_uuid="test-job", + model="meta-llama/Llama-3.1-8B-Instruct", + checkpoint_dir="test-dir", # Unsupported parameter + algorithm_config=LoraFinetuningConfig( + type="LoRA", + adapter_dim=16, + adapter_dropout=0.1, + apply_lora_to_mlp=True, + apply_lora_to_output=True, + alpha=16, + rank=16, + lora_attn_modules=["q_proj", "k_proj", "v_proj", "o_proj"], + ), + training_config=training_config, + logger_config={"test": "value"}, # Unsupported parameter + hyperparam_search_config={"test": "value"}, # Unsupported parameter + ) + ) + + assert len(w) >= 4 + warning_texts = [str(warning.message) for warning in w] + + fields = [ + "checkpoint_dir", + "hyperparam_search_config", + "logger_config", + "TrainingConfig", + "DataConfig", + "OptimizerConfig", + "max_steps_per_epoch", + "gradient_accumulation_steps", + "max_validation_steps", + "dtype", + # required unsupported parameters + "rank", + "apply_lora_to_output", + "lora_attn_modules", + "apply_lora_to_mlp", + ] + for field in fields: + assert any(field in text for text in warning_texts) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/unit/providers/nvidia/test_supervised_fine_tuning.py b/tests/unit/providers/nvidia/test_supervised_fine_tuning.py new file mode 100644 index 000000000..8ef48e05b --- /dev/null +++ b/tests/unit/providers/nvidia/test_supervised_fine_tuning.py @@ -0,0 +1,295 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import os +import unittest +from unittest.mock import patch +import warnings +import pytest + +from llama_stack_client.types.algorithm_config_param import LoraFinetuningConfig, QatFinetuningConfig +from llama_stack_client.types.post_training_supervised_fine_tune_params import ( + TrainingConfig, + TrainingConfigDataConfig, + TrainingConfigOptimizerConfig, +) + +from llama_stack.providers.remote.post_training.nvidia.post_training import ( + NvidiaPostTrainingAdapter, + NvidiaPostTrainingConfig, + NvidiaPostTrainingJobStatusResponse, + ListNvidiaPostTrainingJobs, + NvidiaPostTrainingJob, +) + + +class TestNvidiaPostTraining(unittest.TestCase): + def setUp(self): + os.environ["NVIDIA_BASE_URL"] = "http://nemo.test" # needed for llm inference + os.environ["NVIDIA_CUSTOMIZER_URL"] = "http://nemo.test" # needed for nemo customizer + + config = NvidiaPostTrainingConfig( + base_url=os.environ["NVIDIA_BASE_URL"], customizer_url=os.environ["NVIDIA_CUSTOMIZER_URL"], api_key=None + ) + self.adapter = NvidiaPostTrainingAdapter(config) + self.make_request_patcher = patch( + "llama_stack.providers.remote.post_training.nvidia.post_training.NvidiaPostTrainingAdapter._make_request" + ) + self.mock_make_request = self.make_request_patcher.start() + + def tearDown(self): + self.make_request_patcher.stop() + + @pytest.fixture(autouse=True) + def inject_fixtures(self, run_async): + self.run_async = run_async + + def _assert_request(self, mock_call, expected_method, expected_path, expected_params=None, expected_json=None): + """Helper method to verify request details in mock calls.""" + call_args = mock_call.call_args + + if expected_method and expected_path: + if isinstance(call_args[0], tuple) and len(call_args[0]) == 2: + assert call_args[0] == (expected_method, expected_path) + else: + assert call_args[1]["method"] == expected_method + assert call_args[1]["path"] == expected_path + + if expected_params: + assert call_args[1]["params"] == expected_params + + if expected_json: + for key, value in expected_json.items(): + assert call_args[1]["json"][key] == value + + def test_supervised_fine_tune(self): + """Test the supervised fine-tuning API call.""" + self.mock_make_request.return_value = { + "id": "cust-JGTaMbJMdqjJU8WbQdN9Q2", + "created_at": "2024-12-09T04:06:28.542884", + "updated_at": "2024-12-09T04:06:28.542884", + "config": { + "schema_version": "1.0", + "id": "af783f5b-d985-4e5b-bbb7-f9eec39cc0b1", + "created_at": "2024-12-09T04:06:28.542657", + "updated_at": "2024-12-09T04:06:28.569837", + "custom_fields": {}, + "name": "meta-llama/Llama-3.1-8B-Instruct", + "base_model": "meta-llama/Llama-3.1-8B-Instruct", + "model_path": "llama-3_1-8b-instruct", + "training_types": [], + "finetuning_types": ["lora"], + "precision": "bf16", + "num_gpus": 4, + "num_nodes": 1, + "micro_batch_size": 1, + "tensor_parallel_size": 1, + "max_seq_length": 4096, + }, + "dataset": { + "schema_version": "1.0", + "id": "dataset-XU4pvGzr5tvawnbVxeJMTb", + "created_at": "2024-12-09T04:06:28.542657", + "updated_at": "2024-12-09T04:06:28.542660", + "custom_fields": {}, + "name": "sample-basic-test", + "version_id": "main", + "version_tags": [], + }, + "hyperparameters": { + "finetuning_type": "lora", + "training_type": "sft", + "batch_size": 16, + "epochs": 2, + "learning_rate": 0.0001, + "lora": {"adapter_dim": 16, "adapter_dropout": 0.1}, + }, + "output_model": "default/job-1234", + "status": "created", + "project": "default", + "custom_fields": {}, + "ownership": {"created_by": "me", "access_policies": {}}, + } + + algorithm_config = LoraFinetuningConfig( + type="LoRA", + adapter_dim=16, + adapter_dropout=0.1, + apply_lora_to_mlp=True, + apply_lora_to_output=True, + alpha=16, + rank=16, + lora_attn_modules=["q_proj", "k_proj", "v_proj", "o_proj"], + ) + + data_config = TrainingConfigDataConfig(dataset_id="sample-basic-test", batch_size=16) + + optimizer_config = TrainingConfigOptimizerConfig( + lr=0.0001, + ) + + training_config = TrainingConfig( + n_epochs=2, + data_config=data_config, + optimizer_config=optimizer_config, + ) + + with warnings.catch_warnings(record=True): + warnings.simplefilter("always") + training_job = self.run_async( + self.adapter.supervised_fine_tune( + job_uuid="1234", + model="meta-llama/Llama-3.1-8B-Instruct", + checkpoint_dir="", + algorithm_config=algorithm_config, + training_config=training_config, + logger_config={}, + hyperparam_search_config={}, + ) + ) + + # check the output is a PostTrainingJob + assert isinstance(training_job, NvidiaPostTrainingJob) + assert training_job.job_uuid == "cust-JGTaMbJMdqjJU8WbQdN9Q2" + + self.mock_make_request.assert_called_once() + self._assert_request( + self.mock_make_request, + "POST", + "/v1/customization/jobs", + expected_json={ + "config": "meta/llama-3.1-8b-instruct", + "dataset": {"name": "sample-basic-test", "namespace": "default"}, + "hyperparameters": { + "training_type": "sft", + "finetuning_type": "lora", + "epochs": 2, + "batch_size": 16, + "learning_rate": 0.0001, + "lora": {"alpha": 16, "adapter_dim": 16, "adapter_dropout": 0.1}, + }, + }, + ) + + def test_supervised_fine_tune_with_qat(self): + algorithm_config = QatFinetuningConfig(type="QAT", quantizer_name="quantizer_name", group_size=1) + data_config = TrainingConfigDataConfig(dataset_id="sample-basic-test", batch_size=16) + optimizer_config = TrainingConfigOptimizerConfig( + lr=0.0001, + ) + training_config = TrainingConfig( + n_epochs=2, + data_config=data_config, + optimizer_config=optimizer_config, + ) + # This will raise NotImplementedError since QAT is not supported + with self.assertRaises(NotImplementedError): + self.run_async( + self.adapter.supervised_fine_tune( + job_uuid="1234", + model="meta-llama/Llama-3.1-8B-Instruct", + checkpoint_dir="", + algorithm_config=algorithm_config, + training_config=training_config, + logger_config={}, + hyperparam_search_config={}, + ) + ) + + def test_get_training_job_status(self): + self.mock_make_request.return_value = { + "created_at": "2024-12-09T04:06:28.580220", + "updated_at": "2024-12-09T04:21:19.852832", + "status": "completed", + "steps_completed": 1210, + "epochs_completed": 2, + "percentage_done": 100.0, + "best_epoch": 2, + "train_loss": 1.718016266822815, + "val_loss": 1.8661999702453613, + } + + job_id = "cust-JGTaMbJMdqjJU8WbQdN9Q2" + + status = self.run_async(self.adapter.get_training_job_status(job_uuid=job_id)) + + assert isinstance(status, NvidiaPostTrainingJobStatusResponse) + assert status.status.value == "completed" + assert status.steps_completed == 1210 + assert status.epochs_completed == 2 + assert status.percentage_done == 100.0 + assert status.best_epoch == 2 + assert status.train_loss == 1.718016266822815 + assert status.val_loss == 1.8661999702453613 + + self.mock_make_request.assert_called_once() + self._assert_request( + self.mock_make_request, "GET", f"/v1/customization/jobs/{job_id}/status", expected_params={"job_id": job_id} + ) + + def test_get_training_jobs(self): + job_id = "cust-JGTaMbJMdqjJU8WbQdN9Q2" + self.mock_make_request.return_value = { + "data": [ + { + "id": job_id, + "created_at": "2024-12-09T04:06:28.542884", + "updated_at": "2024-12-09T04:21:19.852832", + "config": { + "name": "meta-llama/Llama-3.1-8B-Instruct", + "base_model": "meta-llama/Llama-3.1-8B-Instruct", + }, + "dataset": {"name": "default/sample-basic-test"}, + "hyperparameters": { + "finetuning_type": "lora", + "training_type": "sft", + "batch_size": 16, + "epochs": 2, + "learning_rate": 0.0001, + "lora": {"adapter_dim": 16, "adapter_dropout": 0.1}, + }, + "output_model": "default/job-1234", + "status": "completed", + "project": "default", + } + ] + } + + jobs = self.run_async(self.adapter.get_training_jobs()) + + assert isinstance(jobs, ListNvidiaPostTrainingJobs) + assert len(jobs.data) == 1 + job = jobs.data[0] + assert job.job_uuid == job_id + assert job.status.value == "completed" + + self.mock_make_request.assert_called_once() + self._assert_request( + self.mock_make_request, + "GET", + "/v1/customization/jobs", + expected_params={"page": 1, "page_size": 10, "sort": "created_at"}, + ) + + def test_cancel_training_job(self): + self.mock_make_request.return_value = {} # Empty response for successful cancellation + job_id = "cust-JGTaMbJMdqjJU8WbQdN9Q2" + + result = self.run_async(self.adapter.cancel_training_job(job_uuid=job_id)) + + assert result is None + + self.mock_make_request.assert_called_once() + self._assert_request( + self.mock_make_request, + "POST", + f"/v1/customization/jobs/{job_id}/cancel", + expected_params={"job_id": job_id}, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/uv.lock b/uv.lock index 7d5e250cb..b1c95c511 100644 --- a/uv.lock +++ b/uv.lock @@ -1,4 +1,5 @@ version = 1 +revision = 1 requires-python = ">=3.10" resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", @@ -1370,6 +1371,7 @@ docs = [ { name = "tomli" }, ] test = [ + { name = "aiohttp" }, { name = "aiosqlite" }, { name = "autoevals" }, { name = "chardet" }, @@ -1385,6 +1387,7 @@ test = [ { name = "torchvision", version = "0.21.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] unit = [ + { name = "aiohttp" }, { name = "aiosqlite" }, { name = "chardet" }, { name = "openai" }, @@ -1395,6 +1398,8 @@ unit = [ [package.metadata] requires-dist = [ + { name = "aiohttp", marker = "extra == 'test'" }, + { name = "aiohttp", marker = "extra == 'unit'" }, { name = "aiosqlite", marker = "extra == 'test'" }, { name = "aiosqlite", marker = "extra == 'unit'" }, { name = "autoevals", marker = "extra == 'test'" }, @@ -1455,6 +1460,7 @@ requires-dist = [ { name = "types-setuptools", marker = "extra == 'dev'" }, { name = "uvicorn", marker = "extra == 'dev'" }, ] +provides-extras = ["dev", "unit", "test", "docs", "codegen"] [[package]] name = "llama-stack-client" From 77ad120403c823a67c2ab1cc5044f30725d54157 Mon Sep 17 00:00:00 2001 From: Yuan Tang Date: Tue, 25 Mar 2025 14:40:55 -0400 Subject: [PATCH 05/45] docs: Add changelog for v0.1.7 and v0.1.8 (#1780) # What does this PR do? This updates the changelog manually for now until we fix the changelog workflow that requires change in repo settings (see [my comment in Discord](https://discordapp.com/channels/1257833999603335178/1337516002535014492/1354127000138289223)). --------- Signed-off-by: Yuan Tang --- CHANGELOG.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62862ebdc..953d04def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,76 @@ # Changelog +# v0.1.8 +Published on: 2025-03-24T01:28:50Z + +# v0.1.8 Release Notes + +### Build and Test Agents +* Safety: Integrated NVIDIA as a safety provider. +* VectorDB: Added Qdrant as an inline provider. +* Agents: Added support for multiple tool groups in agents. +* Agents: Simplified imports for Agents in client package + + +### Agent Evals and Model Customization +* Introduced DocVQA and IfEval benchmarks. + +### Deploying and Monitoring Agents +* Introduced a Containerfile and image workflow for the Playground. +* Implemented support for Bearer (API Key) authentication. +* Added attribute-based access control for resources. +* Fixes on docker deployments: use --pull always and standardized the default port to 8321 +* Deprecated: /v1/inspect/providers use /v1/providers/ instead + +### Better Engineering +* Consolidated scripts under the ./scripts directory. +* Addressed mypy violations in various modules. +* Added Dependabot scans for Python dependencies. +* Implemented a scheduled workflow to update the changelog automatically. +* Enforced concurrency to reduce CI loads. + + +### New Contributors +* @cmodi-meta made their first contribution in https://github.com/meta-llama/llama-stack/pull/1650 +* @jeffmaury made their first contribution in https://github.com/meta-llama/llama-stack/pull/1671 +* @derekhiggins made their first contribution in https://github.com/meta-llama/llama-stack/pull/1698 +* @Bobbins228 made their first contribution in https://github.com/meta-llama/llama-stack/pull/1745 + +**Full Changelog**: https://github.com/meta-llama/llama-stack/compare/v0.1.7...v0.1.8 + +--- + +# v0.1.7 +Published on: 2025-03-14T22:30:51Z + +## 0.1.7 Release Notes + +### Build and Test Agents +* Inference: ImageType is now refactored to LlamaStackImageType +* Inference: Added tests to measure TTFT +* Inference: Bring back usage metrics +* Agents: Added endpoint for get agent, list agents and list sessions +* Agents: Automated conversion of type hints in client tool for lite llm format +* Agents: Deprecated ToolResponseMessage in agent.resume API +* Added Provider API for listing and inspecting provider info + +### Agent Evals and Model Customization +* Eval: Added new eval benchmarks Math 500 and BFCL v3 +* Deploy and Monitoring of Agents +* Telemetry: Fix tracing to work across coroutines + +### Better Engineering +* Display code coverage for unit tests +* Updated call sites (inference, tool calls, agents) to move to async non blocking calls +* Unit tests also run on Python 3.11, 3.12, and 3.13 +* Added ollama inference to Integration tests CI +* Improved documentation across examples, testing, CLI, updated providers table ) + + + + +--- + # v0.1.6 Published on: 2025-03-08T04:35:08Z From 2f38851751f3d1999f8c07853d7800ae56459364 Mon Sep 17 00:00:00 2001 From: ehhuang Date: Tue, 25 Mar 2025 14:42:05 -0700 Subject: [PATCH 06/45] chore: Revert "chore(telemetry): remove service_name entirely" (#1785) Reverts meta-llama/llama-stack#1755 closes #1781 --- .../providers/inline/telemetry/meta_reference/config.py | 6 ++++++ .../providers/inline/telemetry/meta_reference/telemetry.py | 3 +-- llama_stack/templates/bedrock/run.yaml | 1 + llama_stack/templates/cerebras/run.yaml | 1 + llama_stack/templates/ci-tests/run.yaml | 1 + llama_stack/templates/dell/run-with-safety.yaml | 1 + llama_stack/templates/dell/run.yaml | 1 + llama_stack/templates/dev/run.yaml | 1 + llama_stack/templates/fireworks/run-with-safety.yaml | 1 + llama_stack/templates/fireworks/run.yaml | 1 + llama_stack/templates/groq/run.yaml | 1 + llama_stack/templates/hf-endpoint/run-with-safety.yaml | 1 + llama_stack/templates/hf-endpoint/run.yaml | 1 + llama_stack/templates/hf-serverless/run-with-safety.yaml | 1 + llama_stack/templates/hf-serverless/run.yaml | 1 + .../templates/meta-reference-gpu/run-with-safety.yaml | 1 + llama_stack/templates/meta-reference-gpu/run.yaml | 1 + llama_stack/templates/meta-reference-quantized-gpu/run.yaml | 1 + llama_stack/templates/nvidia/run-with-safety.yaml | 1 + llama_stack/templates/nvidia/run.yaml | 1 + llama_stack/templates/ollama/run-with-safety.yaml | 1 + llama_stack/templates/ollama/run.yaml | 1 + llama_stack/templates/open-benchmark/run.yaml | 1 + llama_stack/templates/passthrough/run-with-safety.yaml | 1 + llama_stack/templates/passthrough/run.yaml | 1 + llama_stack/templates/remote-vllm/run-with-safety.yaml | 1 + llama_stack/templates/remote-vllm/run.yaml | 1 + llama_stack/templates/sambanova/run.yaml | 1 + llama_stack/templates/tgi/run-with-safety.yaml | 1 + llama_stack/templates/tgi/run.yaml | 1 + llama_stack/templates/together/run-with-safety.yaml | 1 + llama_stack/templates/together/run.yaml | 1 + llama_stack/templates/vllm-gpu/run.yaml | 1 + 33 files changed, 38 insertions(+), 2 deletions(-) diff --git a/llama_stack/providers/inline/telemetry/meta_reference/config.py b/llama_stack/providers/inline/telemetry/meta_reference/config.py index cdd7063e6..57312f41f 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/config.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/config.py @@ -28,6 +28,11 @@ class TelemetryConfig(BaseModel): default="http://localhost:4318/v1/metrics", description="The OpenTelemetry collector endpoint URL for metrics", ) + service_name: str = Field( + # service name is always the same, use zero-width space to avoid clutter + default="​", + description="The service name to use for telemetry", + ) sinks: List[TelemetrySink] = Field( default=[TelemetrySink.CONSOLE, TelemetrySink.SQLITE], description="List of telemetry sinks to enable (possible values: otel, sqlite, console)", @@ -47,6 +52,7 @@ class TelemetryConfig(BaseModel): @classmethod def sample_run_config(cls, __distro_dir__: str, db_name: str = "trace_store.db") -> Dict[str, Any]: return { + "service_name": "${env.OTEL_SERVICE_NAME:​}", "sinks": "${env.TELEMETRY_SINKS:console,sqlite}", "sqlite_db_path": "${env.SQLITE_DB_PATH:" + __distro_dir__ + "/" + db_name + "}", } diff --git a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py index 181bfda9b..7e834451d 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py @@ -67,8 +67,7 @@ class TelemetryAdapter(TelemetryDatasetMixin, Telemetry): resource = Resource.create( { - # service name is always the same, use zero-width space to avoid clutter - ResourceAttributes.SERVICE_NAME: "​", + ResourceAttributes.SERVICE_NAME: self.config.service_name, } ) diff --git a/llama_stack/templates/bedrock/run.yaml b/llama_stack/templates/bedrock/run.yaml index 07614417a..fe21d4bef 100644 --- a/llama_stack/templates/bedrock/run.yaml +++ b/llama_stack/templates/bedrock/run.yaml @@ -39,6 +39,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/bedrock/trace_store.db} eval: diff --git a/llama_stack/templates/cerebras/run.yaml b/llama_stack/templates/cerebras/run.yaml index 3d4159a5a..dc7ee4729 100644 --- a/llama_stack/templates/cerebras/run.yaml +++ b/llama_stack/templates/cerebras/run.yaml @@ -79,6 +79,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/cerebras/trace_store.db} tool_runtime: diff --git a/llama_stack/templates/ci-tests/run.yaml b/llama_stack/templates/ci-tests/run.yaml index d8cd33414..04bbe212e 100644 --- a/llama_stack/templates/ci-tests/run.yaml +++ b/llama_stack/templates/ci-tests/run.yaml @@ -42,6 +42,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/ci-tests/trace_store.db} eval: diff --git a/llama_stack/templates/dell/run-with-safety.yaml b/llama_stack/templates/dell/run-with-safety.yaml index 6d65d7253..802c56aad 100644 --- a/llama_stack/templates/dell/run-with-safety.yaml +++ b/llama_stack/templates/dell/run-with-safety.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/dell/trace_store.db} eval: diff --git a/llama_stack/templates/dell/run.yaml b/llama_stack/templates/dell/run.yaml index eca0939e8..4a2d819a9 100644 --- a/llama_stack/templates/dell/run.yaml +++ b/llama_stack/templates/dell/run.yaml @@ -41,6 +41,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/dell/trace_store.db} eval: diff --git a/llama_stack/templates/dev/run.yaml b/llama_stack/templates/dev/run.yaml index 627905568..b4546ca58 100644 --- a/llama_stack/templates/dev/run.yaml +++ b/llama_stack/templates/dev/run.yaml @@ -71,6 +71,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/dev/trace_store.db} eval: diff --git a/llama_stack/templates/fireworks/run-with-safety.yaml b/llama_stack/templates/fireworks/run-with-safety.yaml index 45b56696a..125c66177 100644 --- a/llama_stack/templates/fireworks/run-with-safety.yaml +++ b/llama_stack/templates/fireworks/run-with-safety.yaml @@ -50,6 +50,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/fireworks/trace_store.db} eval: diff --git a/llama_stack/templates/fireworks/run.yaml b/llama_stack/templates/fireworks/run.yaml index 840071694..7b3c059e5 100644 --- a/llama_stack/templates/fireworks/run.yaml +++ b/llama_stack/templates/fireworks/run.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/fireworks/trace_store.db} eval: diff --git a/llama_stack/templates/groq/run.yaml b/llama_stack/templates/groq/run.yaml index d2d7cb621..6c83ed43d 100644 --- a/llama_stack/templates/groq/run.yaml +++ b/llama_stack/templates/groq/run.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/groq/trace_store.db} eval: diff --git a/llama_stack/templates/hf-endpoint/run-with-safety.yaml b/llama_stack/templates/hf-endpoint/run-with-safety.yaml index be2b419ce..14753e08b 100644 --- a/llama_stack/templates/hf-endpoint/run-with-safety.yaml +++ b/llama_stack/templates/hf-endpoint/run-with-safety.yaml @@ -50,6 +50,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/hf-endpoint/trace_store.db} eval: diff --git a/llama_stack/templates/hf-endpoint/run.yaml b/llama_stack/templates/hf-endpoint/run.yaml index 1c9b2a864..706ba9122 100644 --- a/llama_stack/templates/hf-endpoint/run.yaml +++ b/llama_stack/templates/hf-endpoint/run.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/hf-endpoint/trace_store.db} eval: diff --git a/llama_stack/templates/hf-serverless/run-with-safety.yaml b/llama_stack/templates/hf-serverless/run-with-safety.yaml index 0e8858ea2..bf26fe507 100644 --- a/llama_stack/templates/hf-serverless/run-with-safety.yaml +++ b/llama_stack/templates/hf-serverless/run-with-safety.yaml @@ -50,6 +50,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/hf-serverless/trace_store.db} eval: diff --git a/llama_stack/templates/hf-serverless/run.yaml b/llama_stack/templates/hf-serverless/run.yaml index 3f971c29b..cc973b8de 100644 --- a/llama_stack/templates/hf-serverless/run.yaml +++ b/llama_stack/templates/hf-serverless/run.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/hf-serverless/trace_store.db} eval: diff --git a/llama_stack/templates/meta-reference-gpu/run-with-safety.yaml b/llama_stack/templates/meta-reference-gpu/run-with-safety.yaml index 866575e26..2cf49cc36 100644 --- a/llama_stack/templates/meta-reference-gpu/run-with-safety.yaml +++ b/llama_stack/templates/meta-reference-gpu/run-with-safety.yaml @@ -52,6 +52,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/meta-reference-gpu/trace_store.db} eval: diff --git a/llama_stack/templates/meta-reference-gpu/run.yaml b/llama_stack/templates/meta-reference-gpu/run.yaml index e2a4d3065..964dfafeb 100644 --- a/llama_stack/templates/meta-reference-gpu/run.yaml +++ b/llama_stack/templates/meta-reference-gpu/run.yaml @@ -46,6 +46,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/meta-reference-gpu/trace_store.db} eval: diff --git a/llama_stack/templates/meta-reference-quantized-gpu/run.yaml b/llama_stack/templates/meta-reference-quantized-gpu/run.yaml index d1b19db75..f934ecfbb 100644 --- a/llama_stack/templates/meta-reference-quantized-gpu/run.yaml +++ b/llama_stack/templates/meta-reference-quantized-gpu/run.yaml @@ -48,6 +48,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/meta-reference-quantized-gpu/trace_store.db} eval: diff --git a/llama_stack/templates/nvidia/run-with-safety.yaml b/llama_stack/templates/nvidia/run-with-safety.yaml index d4e9e0d33..658d9377e 100644 --- a/llama_stack/templates/nvidia/run-with-safety.yaml +++ b/llama_stack/templates/nvidia/run-with-safety.yaml @@ -49,6 +49,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/nvidia/trace_store.db} eval: diff --git a/llama_stack/templates/nvidia/run.yaml b/llama_stack/templates/nvidia/run.yaml index 9df324bfc..1267a9883 100644 --- a/llama_stack/templates/nvidia/run.yaml +++ b/llama_stack/templates/nvidia/run.yaml @@ -44,6 +44,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/nvidia/trace_store.db} eval: diff --git a/llama_stack/templates/ollama/run-with-safety.yaml b/llama_stack/templates/ollama/run-with-safety.yaml index 618745f5d..b43fec6db 100644 --- a/llama_stack/templates/ollama/run-with-safety.yaml +++ b/llama_stack/templates/ollama/run-with-safety.yaml @@ -43,6 +43,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/ollama/trace_store.db} eval: diff --git a/llama_stack/templates/ollama/run.yaml b/llama_stack/templates/ollama/run.yaml index 889c80a62..c8f4ad9ad 100644 --- a/llama_stack/templates/ollama/run.yaml +++ b/llama_stack/templates/ollama/run.yaml @@ -41,6 +41,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/ollama/trace_store.db} eval: diff --git a/llama_stack/templates/open-benchmark/run.yaml b/llama_stack/templates/open-benchmark/run.yaml index 5d8625a2b..5e908b081 100644 --- a/llama_stack/templates/open-benchmark/run.yaml +++ b/llama_stack/templates/open-benchmark/run.yaml @@ -68,6 +68,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/open-benchmark/trace_store.db} eval: diff --git a/llama_stack/templates/passthrough/run-with-safety.yaml b/llama_stack/templates/passthrough/run-with-safety.yaml index 63a1c3a7b..8ab6b1081 100644 --- a/llama_stack/templates/passthrough/run-with-safety.yaml +++ b/llama_stack/templates/passthrough/run-with-safety.yaml @@ -50,6 +50,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/passthrough/trace_store.db} eval: diff --git a/llama_stack/templates/passthrough/run.yaml b/llama_stack/templates/passthrough/run.yaml index 6d3184adc..53e8c8857 100644 --- a/llama_stack/templates/passthrough/run.yaml +++ b/llama_stack/templates/passthrough/run.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/passthrough/trace_store.db} eval: diff --git a/llama_stack/templates/remote-vllm/run-with-safety.yaml b/llama_stack/templates/remote-vllm/run-with-safety.yaml index 23ef7134b..bb69496aa 100644 --- a/llama_stack/templates/remote-vllm/run-with-safety.yaml +++ b/llama_stack/templates/remote-vllm/run-with-safety.yaml @@ -88,6 +88,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/remote-vllm/trace_store.db} tool_runtime: diff --git a/llama_stack/templates/remote-vllm/run.yaml b/llama_stack/templates/remote-vllm/run.yaml index b52f6ed50..14f2da37e 100644 --- a/llama_stack/templates/remote-vllm/run.yaml +++ b/llama_stack/templates/remote-vllm/run.yaml @@ -81,6 +81,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/remote-vllm/trace_store.db} tool_runtime: diff --git a/llama_stack/templates/sambanova/run.yaml b/llama_stack/templates/sambanova/run.yaml index e249d77ad..a64ada759 100644 --- a/llama_stack/templates/sambanova/run.yaml +++ b/llama_stack/templates/sambanova/run.yaml @@ -51,6 +51,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/sambanova/trace_store.db} tool_runtime: diff --git a/llama_stack/templates/tgi/run-with-safety.yaml b/llama_stack/templates/tgi/run-with-safety.yaml index fd1a85fd3..12d6bd284 100644 --- a/llama_stack/templates/tgi/run-with-safety.yaml +++ b/llama_stack/templates/tgi/run-with-safety.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/tgi/trace_store.db} eval: diff --git a/llama_stack/templates/tgi/run.yaml b/llama_stack/templates/tgi/run.yaml index f370fa154..9f05c7584 100644 --- a/llama_stack/templates/tgi/run.yaml +++ b/llama_stack/templates/tgi/run.yaml @@ -44,6 +44,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/tgi/trace_store.db} eval: diff --git a/llama_stack/templates/together/run-with-safety.yaml b/llama_stack/templates/together/run-with-safety.yaml index ec72b3db0..1fbf64e40 100644 --- a/llama_stack/templates/together/run-with-safety.yaml +++ b/llama_stack/templates/together/run-with-safety.yaml @@ -50,6 +50,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/together/trace_store.db} eval: diff --git a/llama_stack/templates/together/run.yaml b/llama_stack/templates/together/run.yaml index 7e0fb481f..d71aea640 100644 --- a/llama_stack/templates/together/run.yaml +++ b/llama_stack/templates/together/run.yaml @@ -45,6 +45,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/together/trace_store.db} eval: diff --git a/llama_stack/templates/vllm-gpu/run.yaml b/llama_stack/templates/vllm-gpu/run.yaml index afdede526..a839aa2c5 100644 --- a/llama_stack/templates/vllm-gpu/run.yaml +++ b/llama_stack/templates/vllm-gpu/run.yaml @@ -49,6 +49,7 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: + service_name: "${env.OTEL_SERVICE_NAME:\u200B}" sinks: ${env.TELEMETRY_SINKS:console,sqlite} sqlite_db_path: ${env.SQLITE_DB_PATH:~/.llama/distributions/vllm-gpu/trace_store.db} eval: From c8f740353b891d8b584507c3ba5e827cdeeb99fe Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 25 Mar 2025 18:49:29 -0400 Subject: [PATCH 07/45] chore: enable mypy pydantic plugin (#1788) # What does this PR do? Enable mypy pydantic plugin. Since the project heavily relies on pydantic models, it's probably wise to enable the plugin to avoid some potential spurious violation warnings the further we expand mypy coverage for the code base. It should be generally risk-free to enable the plugin for the repo. Some info on what plugin brings to the table: https://docs.pydantic.dev/latest/integrations/mypy/#mypy-plugin-capabilities Signed-off-by: Ihar Hrachyshka --- pyproject.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0b34a601c..9eef66672 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -152,6 +152,7 @@ ignore = [ [tool.mypy] mypy_path = ["llama_stack"] packages = ["llama_stack"] +plugins = ['pydantic.mypy'] disable_error_code = [] warn_return_any = true # # honor excludes by not following there through imports @@ -304,3 +305,8 @@ exclude = [ # packages that lack typing annotations, do not have stubs, or are unavailable. module = ["yaml", "fire"] ignore_missing_imports = true + +[tool.pydantic-mypy] +init_forbid_extra = true +init_typed = true +warn_required_dynamic_aliases = true From 65d5d0d1bf2c30a7f78352a4f023d731646b54f7 Mon Sep 17 00:00:00 2001 From: Xi Yan Date: Tue, 25 Mar 2025 16:06:03 -0700 Subject: [PATCH 08/45] fix: fix imports for mcp registration in notebook (#1787) # What does this PR do? - as title [//]: # (If resolving an issue, uncomment and update the line below) [//]: # (Closes #[issue-number]) ## Test Plan notebook [//]: # (## Documentation) --- docs/getting_started.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb index 05b0d1357..cdf899411 100644 --- a/docs/getting_started.ipynb +++ b/docs/getting_started.ipynb @@ -2519,11 +2519,11 @@ "outputs": [], "source": [ "# NBVAL_SKIP\n", - "from llama_stack_client.types.shared_params.url import URL\n", + "from llama_stack_client.types.tool_group import McpEndpoint\n", "client.toolgroups.register(\n", " toolgroup_id=\"mcp::filesystem\",\n", " provider_id=\"model-context-protocol\",\n", - " mcp_endpoint=URL(uri=\"http://localhost:8000/sse\"),\n", + " mcp_endpoint=McpEndpoint(uri=\"http://localhost:8000/sse\"),\n", ")" ] }, From 367c08f01e7f6c5b7e1365784a093bf3da97ea77 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 25 Mar 2025 20:12:36 -0400 Subject: [PATCH 09/45] feat(api): don't return a payload on file delete (#1640) # What does this PR do? This is to stay consistent with other APIs. This change registers files in API, even though there are still no providers. Removing tests that require a provider existing for a merged API to enable it in API layer. Signed-off-by: Ihar Hrachyshka [//]: # (If resolving an issue, uncomment and update the line below) [//]: # (Closes #[issue-number]) ## Test Plan [Describe the tests you ran to verify your changes with result summaries. *Provide clear instructions so the plan can be easily re-executed.*] [//]: # (## Documentation) Signed-off-by: Ihar Hrachyshka --- docs/_static/llama-stack-spec.html | 89 ++++++++++----------- docs/_static/llama-stack-spec.yaml | 70 ++++++++-------- docs/openapi_generator/generate.py | 5 +- docs/openapi_generator/pyopenapi/utility.py | 75 +++++++++++------ llama_stack/apis/datatypes.py | 1 + llama_stack/apis/files/files.py | 2 +- llama_stack/distribution/resolver.py | 2 + llama_stack/providers/registry/files.py | 11 +++ tests/unit/providers/test_configs.py | 7 -- 9 files changed, 143 insertions(+), 119 deletions(-) create mode 100644 llama_stack/providers/registry/files.py diff --git a/docs/_static/llama-stack-spec.html b/docs/_static/llama-stack-spec.html index 7b1b6a0b6..4990d845e 100644 --- a/docs/_static/llama-stack-spec.html +++ b/docs/_static/llama-stack-spec.html @@ -818,14 +818,7 @@ "delete": { "responses": { "200": { - "description": "OK", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FileResponse" - } - } - } + "description": "OK" }, "400": { "$ref": "#/components/responses/BadRequest400" @@ -6140,46 +6133,6 @@ "title": "FileUploadResponse", "description": "Response after initiating a file upload session." }, - "FileResponse": { - "type": "object", - "properties": { - "bucket": { - "type": "string", - "description": "Bucket under which the file is stored (valid chars: a-zA-Z0-9_-)" - }, - "key": { - "type": "string", - "description": "Key under which the file is stored (valid chars: a-zA-Z0-9_-/.)" - }, - "mime_type": { - "type": "string", - "description": "MIME type of the file" - }, - "url": { - "type": "string", - "description": "Upload URL for the file contents" - }, - "bytes": { - "type": "integer", - "description": "Size of the file in bytes" - }, - "created_at": { - "type": "integer", - "description": "Timestamp of when the file was created" - } - }, - "additionalProperties": false, - "required": [ - "bucket", - "key", - "mime_type", - "url", - "bytes", - "created_at" - ], - "title": "FileResponse", - "description": "Response representing a file entry." - }, "EmbeddingsRequest": { "type": "object", "properties": { @@ -6933,6 +6886,46 @@ "title": "URIDataSource", "description": "A dataset that can be obtained from a URI." }, + "FileResponse": { + "type": "object", + "properties": { + "bucket": { + "type": "string", + "description": "Bucket under which the file is stored (valid chars: a-zA-Z0-9_-)" + }, + "key": { + "type": "string", + "description": "Key under which the file is stored (valid chars: a-zA-Z0-9_-/.)" + }, + "mime_type": { + "type": "string", + "description": "MIME type of the file" + }, + "url": { + "type": "string", + "description": "Upload URL for the file contents" + }, + "bytes": { + "type": "integer", + "description": "Size of the file in bytes" + }, + "created_at": { + "type": "integer", + "description": "Timestamp of when the file was created" + } + }, + "additionalProperties": false, + "required": [ + "bucket", + "key", + "mime_type", + "url", + "bytes", + "created_at" + ], + "title": "FileResponse", + "description": "Response representing a file entry." + }, "Model": { "type": "object", "properties": { diff --git a/docs/_static/llama-stack-spec.yaml b/docs/_static/llama-stack-spec.yaml index a815931de..ba3868560 100644 --- a/docs/_static/llama-stack-spec.yaml +++ b/docs/_static/llama-stack-spec.yaml @@ -557,10 +557,6 @@ paths: responses: '200': description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/FileResponse' '400': $ref: '#/components/responses/BadRequest400' '429': @@ -4286,39 +4282,6 @@ components: title: FileUploadResponse description: >- Response after initiating a file upload session. - FileResponse: - type: object - properties: - bucket: - type: string - description: >- - Bucket under which the file is stored (valid chars: a-zA-Z0-9_-) - key: - type: string - description: >- - Key under which the file is stored (valid chars: a-zA-Z0-9_-/.) - mime_type: - type: string - description: MIME type of the file - url: - type: string - description: Upload URL for the file contents - bytes: - type: integer - description: Size of the file in bytes - created_at: - type: integer - description: Timestamp of when the file was created - additionalProperties: false - required: - - bucket - - key - - mime_type - - url - - bytes - - created_at - title: FileResponse - description: Response representing a file entry. EmbeddingsRequest: type: object properties: @@ -4830,6 +4793,39 @@ components: title: URIDataSource description: >- A dataset that can be obtained from a URI. + FileResponse: + type: object + properties: + bucket: + type: string + description: >- + Bucket under which the file is stored (valid chars: a-zA-Z0-9_-) + key: + type: string + description: >- + Key under which the file is stored (valid chars: a-zA-Z0-9_-/.) + mime_type: + type: string + description: MIME type of the file + url: + type: string + description: Upload URL for the file contents + bytes: + type: integer + description: Size of the file in bytes + created_at: + type: integer + description: Timestamp of when the file was created + additionalProperties: false + required: + - bucket + - key + - mime_type + - url + - bytes + - created_at + title: FileResponse + description: Response representing a file entry. Model: type: object properties: diff --git a/docs/openapi_generator/generate.py b/docs/openapi_generator/generate.py index 879ac95e2..a3c27cf4e 100644 --- a/docs/openapi_generator/generate.py +++ b/docs/openapi_generator/generate.py @@ -21,7 +21,7 @@ from llama_stack.distribution.stack import LlamaStack # noqa: E402 from .pyopenapi.options import Options # noqa: E402 from .pyopenapi.specification import Info, Server # noqa: E402 -from .pyopenapi.utility import Specification, validate_api_method_return_types # noqa: E402 +from .pyopenapi.utility import Specification, validate_api # noqa: E402 def str_presenter(dumper, data): @@ -40,8 +40,7 @@ def main(output_dir: str): raise ValueError(f"Directory {output_dir} does not exist") # Validate API protocols before generating spec - print("Validating API method return types...") - return_type_errors = validate_api_method_return_types() + return_type_errors = validate_api() if return_type_errors: print("\nAPI Method Return Type Validation Errors:\n") for error in return_type_errors: diff --git a/docs/openapi_generator/pyopenapi/utility.py b/docs/openapi_generator/pyopenapi/utility.py index f60a33bb7..cb155fed7 100644 --- a/docs/openapi_generator/pyopenapi/utility.py +++ b/docs/openapi_generator/pyopenapi/utility.py @@ -7,10 +7,9 @@ import json import typing import inspect -import os from pathlib import Path from typing import TextIO -from typing import Any, Dict, List, Optional, Protocol, Type, Union, get_type_hints, get_origin, get_args +from typing import Any, List, Optional, Union, get_type_hints, get_origin, get_args from llama_stack.strong_typing.schema import object_to_json, StrictJsonType from llama_stack.distribution.resolver import api_protocol_map @@ -125,29 +124,59 @@ def is_optional_type(type_: Any) -> bool: return origin is Optional or (origin is Union and type(None) in args) -def validate_api_method_return_types() -> List[str]: - """Validate that all API methods have proper return types.""" +def _validate_api_method_return_type(method) -> str | None: + hints = get_type_hints(method) + + if 'return' not in hints: + return "has no return type annotation" + + return_type = hints['return'] + if is_optional_type(return_type): + return "returns Optional type" + + +def _validate_api_delete_method_returns_none(method) -> str | None: + hints = get_type_hints(method) + + if 'return' not in hints: + return "has no return type annotation" + + return_type = hints['return'] + if return_type is not None and return_type is not type(None): + return "does not return None" + + +_VALIDATORS = { + "GET": [ + _validate_api_method_return_type, + ], + "DELETE": [ + _validate_api_delete_method_returns_none, + ], +} + + +def _get_methods_by_type(protocol, method_type: str): + members = inspect.getmembers(protocol, predicate=inspect.isfunction) + return { + method_name: method + for method_name, method in members + if (webmethod := getattr(method, '__webmethod__', None)) + if webmethod and webmethod.method == method_type + } + + +def validate_api() -> List[str]: + """Validate the API protocols.""" errors = [] protocols = api_protocol_map() - for protocol_name, protocol in protocols.items(): - methods = inspect.getmembers(protocol, predicate=inspect.isfunction) - - for method_name, method in methods: - if not hasattr(method, '__webmethod__'): - continue - - # Only check GET methods - if method.__webmethod__.method != "GET": - continue - - hints = get_type_hints(method) - - if 'return' not in hints: - errors.append(f"Method {protocol_name}.{method_name} has no return type annotation") - else: - return_type = hints['return'] - if is_optional_type(return_type): - errors.append(f"Method {protocol_name}.{method_name} returns Optional type") + for target, validators in _VALIDATORS.items(): + for protocol_name, protocol in protocols.items(): + for validator in validators: + for method_name, method in _get_methods_by_type(protocol, target).items(): + err = validator(method) + if err: + errors.append(f"Method {protocol_name}.{method_name} {err}") return errors diff --git a/llama_stack/apis/datatypes.py b/llama_stack/apis/datatypes.py index f644e5137..25f3ab1ab 100644 --- a/llama_stack/apis/datatypes.py +++ b/llama_stack/apis/datatypes.py @@ -34,6 +34,7 @@ class Api(Enum): scoring_functions = "scoring_functions" benchmarks = "benchmarks" tool_groups = "tool_groups" + files = "files" # built-in API inspect = "inspect" diff --git a/llama_stack/apis/files/files.py b/llama_stack/apis/files/files.py index 65c1ead6a..ef8b65829 100644 --- a/llama_stack/apis/files/files.py +++ b/llama_stack/apis/files/files.py @@ -164,7 +164,7 @@ class Files(Protocol): self, bucket: str, key: str, - ) -> FileResponse: + ) -> None: """ Delete a file identified by a bucket and key. diff --git a/llama_stack/distribution/resolver.py b/llama_stack/distribution/resolver.py index e9e406699..25fe3f184 100644 --- a/llama_stack/distribution/resolver.py +++ b/llama_stack/distribution/resolver.py @@ -12,6 +12,7 @@ from llama_stack.apis.benchmarks import Benchmarks from llama_stack.apis.datasetio import DatasetIO from llama_stack.apis.datasets import Datasets from llama_stack.apis.eval import Eval +from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference from llama_stack.apis.inspect import Inspect from llama_stack.apis.models import Models @@ -79,6 +80,7 @@ def api_protocol_map() -> Dict[Api, Any]: Api.post_training: PostTraining, Api.tool_groups: ToolGroups, Api.tool_runtime: ToolRuntime, + Api.files: Files, } diff --git a/llama_stack/providers/registry/files.py b/llama_stack/providers/registry/files.py new file mode 100644 index 000000000..fb23436bb --- /dev/null +++ b/llama_stack/providers/registry/files.py @@ -0,0 +1,11 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from llama_stack.providers.datatypes import ProviderSpec + + +def available_providers() -> list[ProviderSpec]: + return [] diff --git a/tests/unit/providers/test_configs.py b/tests/unit/providers/test_configs.py index 246470372..99081c8b0 100644 --- a/tests/unit/providers/test_configs.py +++ b/tests/unit/providers/test_configs.py @@ -14,17 +14,10 @@ from llama_stack.distribution.utils.dynamic import instantiate_class_type class TestProviderConfigurations: """Test suite for testing provider configurations across all API types.""" - def test_all_api_providers_exist(self): - provider_registry = get_provider_registry() - for api in providable_apis(): - providers = provider_registry.get(api, {}) - assert providers, f"No providers found for API type: {api}" - @pytest.mark.parametrize("api", providable_apis()) def test_api_providers(self, api): provider_registry = get_provider_registry() providers = provider_registry.get(api, {}) - assert providers, f"No providers found for API type: {api}" failures = [] for provider_type, provider_spec in providers.items(): From bdfe7fee92dd547e71cd395fb34b56d878ad7ac8 Mon Sep 17 00:00:00 2001 From: Yuan Tang Date: Tue, 25 Mar 2025 23:03:21 -0400 Subject: [PATCH 10/45] docs: Add more env vars in dotenv instructions (#1791) # What does this PR do? Added more hint on `LLAMA_STACK_CONFIG` and API keys necessary for agent tests. --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3fd04b93f..21591481e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,9 @@ Note that you can create a dotenv file `.env` that includes necessary environmen LLAMA_STACK_BASE_URL=http://localhost:8321 LLAMA_STACK_CLIENT_LOG=debug LLAMA_STACK_PORT=8321 -LLAMA_STACK_CONFIG= +LLAMA_STACK_CONFIG= +TAVILY_SEARCH_API_KEY= +BRAVE_SEARCH_API_KEY= ``` And then use this dotenv file when running client SDK tests via the following: From cb2a9784abf7ca64fbac02aba7790a71798e3d5d Mon Sep 17 00:00:00 2001 From: Hardik Shah Date: Wed, 26 Mar 2025 10:59:12 -0700 Subject: [PATCH 11/45] fix: multiple issues with getting_started notebook (#1795) Fixes multiple issues 1. llama stack build of dependencies was breaking with incompatible numpy / pandas when importing datasets Moved the notebook to start a local server instead of using library as a client. This way the setup is cleaner since its all contained and by using `uv run --with` we can test both the server setup process too in CI and release time. 2. The change to [1] surfaced some other issues - running `llama stack run` was defaulting to conda env name - provider data was not being managed properly - Some notebook cells (telemetry for evals) were not updated with latest changes Fixed all the issues and update the notebook. ### Test 1. Manually run it all in local env 2. `pytest -v -s --nbval-lax docs/getting_started.ipynb` --- docs/getting_started.ipynb | 2247 ++++----------------- llama_stack/cli/stack/run.py | 2 +- llama_stack/distribution/start_stack.sh | 26 +- llama_stack/distribution/utils/context.py | 12 +- 4 files changed, 445 insertions(+), 1842 deletions(-) diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb index cdf899411..f13a26a5a 100644 --- a/docs/getting_started.ipynb +++ b/docs/getting_started.ipynb @@ -62,16 +62,18 @@ "id": "oDUB7M_qe-Gs" }, "source": [ - "### 1.2. Install Llama Stack\n", + "### 1.2. Setup and Running a Llama Stack server\n", "\n", - "We will now start with installing the [llama-stack pypi package](https://pypi.org/project/llama-stack).\n", + "Llama Stack is architected as a collection of APIs that provide developers with the building blocks to build AI applications. \n", "\n", - "In addition, we will install [bubblewrap](https://github.com/containers/bubblewrap), a low level light-weight container framework that runs in the user namespace. We will use it to execute code generated by Llama in one of the examples." + "Llama stack is typically available as a server with an endpoint that you can make calls to. Partners like Together and Fireworks offer their own Llama Stack compatible endpoints.\n", + "\n", + "In this showcase, we will start a Llama Stack server that is running locally.\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "J2kGed0R5PSf", "metadata": { "colab": { @@ -81,69 +83,164 @@ "id": "J2kGed0R5PSf", "outputId": "2478ea60-8d35-48a1-b011-f233831740c5" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: uv in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (0.5.29)\n", + "Environment '/Users/hjshah/git/llama-stack/.venv' already exists, re-using it.\n", + "Virtual environment /Users/hjshah/git/llama-stack/.venv is already active\n", + "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", + "\u001b[2mAudited \u001b[1m1 package\u001b[0m \u001b[2min 314ms\u001b[0m\u001b[0m\n", + "Installing pip dependencies\n", + "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", + "\u001b[2K\u001b[2mResolved \u001b[1m125 packages\u001b[0m \u001b[2min 646ms\u001b[0m\u001b[0m \u001b[0m\n", + "\u001b[2mUninstalled \u001b[1m1 package\u001b[0m \u001b[2min 404ms\u001b[0m\u001b[0m\n", + "\u001b[2K\u001b[2mInstalled \u001b[1m1 package\u001b[0m \u001b[2min 129ms\u001b[0m\u001b[0m \u001b[0m\n", + " \u001b[31m-\u001b[39m \u001b[1mnumpy\u001b[0m\u001b[2m==2.2.3\u001b[0m\n", + " \u001b[32m+\u001b[39m \u001b[1mnumpy\u001b[0m\u001b[2m==1.26.4\u001b[0m\n", + "sentence-transformers --no-deps\n", + "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", + "\u001b[2mAudited \u001b[1m1 package\u001b[0m \u001b[2min 54ms\u001b[0m\u001b[0m\n", + "torch torchvision --index-url https://download.pytorch.org/whl/cpu\n", + "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", + "\u001b[2mAudited \u001b[1m2 packages\u001b[0m \u001b[2min 10ms\u001b[0m\u001b[0m\n", + "\u001b[32mBuild Successful!\u001b[0m\n" + ] + } + ], "source": [ - "# NBVAL_SKIP\n", - "!apt-get install -y bubblewrap\n", - "!pip install -U llama-stack" + "import os \n", + "import subprocess\n", + "import time\n", + "\n", + "!pip install uv \n", + "\n", + "if \"UV_SYSTEM_PYTHON\" in os.environ:\n", + " del os.environ[\"UV_SYSTEM_PYTHON\"]\n", + "\n", + "# this command installs all the dependencies needed for the llama stack server with the together inference provider\n", + "!uv run --with llama-stack llama stack build --template together --image-type venv \n", + "\n", + "def run_llama_stack_server_background():\n", + " log_file = open(\"llama_stack_server.log\", \"w\")\n", + " process = subprocess.Popen(\n", + " \"uv run --with llama-stack llama stack run together --image-type venv\",\n", + " shell=True,\n", + " stdout=log_file,\n", + " stderr=log_file,\n", + " text=True\n", + " )\n", + " \n", + " print(f\"Starting Llama Stack server with PID: {process.pid}\")\n", + " return process\n", + "\n", + "def wait_for_server_to_start():\n", + " import requests\n", + " from requests.exceptions import ConnectionError\n", + " import time\n", + " \n", + " url = \"http://0.0.0.0:8321/v1/health\"\n", + " max_retries = 30\n", + " retry_interval = 1\n", + " \n", + " print(\"Waiting for server to start\", end=\"\")\n", + " for _ in range(max_retries):\n", + " try:\n", + " response = requests.get(url)\n", + " if response.status_code == 200:\n", + " print(\"\\nServer is ready!\")\n", + " return True\n", + " except ConnectionError:\n", + " print(\".\", end=\"\", flush=True)\n", + " time.sleep(retry_interval)\n", + " \n", + " print(\"\\nServer failed to start after\", max_retries * retry_interval, \"seconds\")\n", + " return False\n", + "\n", + "\n", + "# use this helper if needed to kill the server \n", + "def kill_llama_stack_server():\n", + " # Kill any existing llama stack server processes\n", + " os.system(\"ps aux | grep -v grep | grep llama_stack.distribution.server.server | awk '{print $2}' | xargs kill -9\")\n" ] }, { "cell_type": "markdown", - "id": "414301dc", - "metadata": { - "id": "414301dc" - }, + "id": "c40e9efd", + "metadata": {}, "source": [ - "### 1.3. Configure Llama Stack for Together\n", - "\n", - "\n", - "Llama Stack is architected as a collection of lego blocks which can be assembled as needed.\n", - "\n", - "\n", - "Typically, llama stack is available as a server with an endpoint that you can hit. We call this endpoint a [Distribution](https://llama-stack.readthedocs.io/en/latest/concepts/index.html#distributions). Partners like Together and Fireworks offer their own Llama Stack Distribution endpoints.\n", - "\n", - "In this showcase, we are going to use llama stack inline as a library. So, given a particular set of providers, we must first package up the right set of dependencies. We have a template to use Together as an inference provider and [faiss](https://ai.meta.com/tools/faiss/) for memory/RAG.\n", - "\n", - "We will run `llama stack build` to deploy all dependencies." + "### 1.3 Starting the Llama Stack Server" ] }, { "cell_type": "code", - "execution_count": null, - "id": "HaepEZXCDgif", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "HaepEZXCDgif", - "outputId": "9314f698-593d-4c1a-ea15-15c735dc1023" - }, - "outputs": [], + "execution_count": 2, + "id": "f779283d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting Llama Stack server with PID: 79142\n", + "Waiting for server to start..........................\n", + "Server is ready!\n" + ] + } + ], "source": [ - "# NBVAL_SKIP\n", - "!pip uninstall pandas numpy -y\n", - "!pip install pandas numpy\n", - "# This will build all the dependencies you will need\n", - "!UV_SYSTEM_PYTHON=1 llama stack build --template together --image-type venv" + "server_process = run_llama_stack_server_background()\n", + "assert wait_for_server_to_start()" ] }, { "cell_type": "markdown", - "id": "25b97dfe", - "metadata": { - "id": "25b97dfe" - }, + "id": "90eb721b", + "metadata": {}, "source": [ - "### 1.4. Initialize Llama Stack\n", + "### 1.4. Install and Configure the Client\n", "\n", - "Now that all dependencies have been installed, we can initialize llama stack. We will first set the `TOGETHER_API_KEY` environment variable\n" + "Now that we have our Llama Stack server running locally, we need to install the client package to interact with it. The `llama-stack-client` provides a simple Python interface to access all the functionality of Llama Stack, including:\n", + "\n", + "- Chat Completions ( text and multimodal )\n", + "- Safety Shields \n", + "- Agent capabilities with tools like web search, RAG with Telemetry\n", + "- Evaluation and scoring frameworks\n", + "\n", + "The client handles all the API communication with our local server, making it easy to integrate Llama Stack's capabilities into your applications.\n", + "\n", + "In the next cells, we'll:\n", + "\n", + "1. Install the client package\n", + "2. Set up API keys for external services (Together AI and Tavily Search)\n", + "3. Initialize the client to connect to our local server\n" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 3, + "id": "2e68e32a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2mUsing Python 3.10.16 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/stack\u001b[0m\n", + "\u001b[2K\u001b[2mResolved \u001b[1m31 packages\u001b[0m \u001b[2min 284ms\u001b[0m\u001b[0m \u001b[0m\n", + "\u001b[2mAudited \u001b[1m31 packages\u001b[0m \u001b[2min 0.04ms\u001b[0m\u001b[0m\n" + ] + } + ], + "source": [ + "!uv pip install -U llama-stack-client" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "id": "E1UFuJC570Tk", "metadata": { "colab": { @@ -284,561 +381,6 @@ "text": [ "Not in Google Colab environment\n" ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Warning: `bwrap` is not available. Code interpreter tool will not work correctly.\n" - ] - }, - { - "data": { - "text/html": [ - "
Using config together:\n",
-              "
\n" - ], - "text/plain": [ - "Using config \u001b[34mtogether\u001b[0m:\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
apis:\n",
-              "- agents\n",
-              "- datasetio\n",
-              "- eval\n",
-              "- inference\n",
-              "- safety\n",
-              "- scoring\n",
-              "- telemetry\n",
-              "- tool_runtime\n",
-              "- vector_io\n",
-              "benchmarks: []\n",
-              "container_image: null\n",
-              "datasets: []\n",
-              "image_name: together\n",
-              "metadata_store:\n",
-              "  db_path: /Users/xiyan/.llama/distributions/together/registry.db\n",
-              "  namespace: null\n",
-              "  type: sqlite\n",
-              "models:\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.1-8B-Instruct\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.1-70B-Instruct\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.1-405B-Instruct-FP8\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.2-3B-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.2-3B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.2-3B-Instruct\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.2-3B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.2-11B-Vision-Instruct\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.2-90B-Vision-Instruct\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.3-70B-Instruct-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.3-70B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-3.3-70B-Instruct\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-3.3-70B-Instruct-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Meta-Llama-Guard-3-8B\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-Guard-3-8B\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-Guard-3-8B\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Meta-Llama-Guard-3-8B\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-Guard-3-11B-Vision-Turbo\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-Guard-3-11B-Vision-Turbo\n",
-              "- metadata: {}\n",
-              "  model_id: meta-llama/Llama-Guard-3-11B-Vision\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - llm\n",
-              "  provider_id: together\n",
-              "  provider_model_id: meta-llama/Llama-Guard-3-11B-Vision-Turbo\n",
-              "- metadata:\n",
-              "    context_length: 8192\n",
-              "    embedding_dimension: 768\n",
-              "  model_id: togethercomputer/m2-bert-80M-8k-retrieval\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - embedding\n",
-              "  provider_id: together\n",
-              "  provider_model_id: togethercomputer/m2-bert-80M-8k-retrieval\n",
-              "- metadata:\n",
-              "    context_length: 32768\n",
-              "    embedding_dimension: 768\n",
-              "  model_id: togethercomputer/m2-bert-80M-32k-retrieval\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - embedding\n",
-              "  provider_id: together\n",
-              "  provider_model_id: togethercomputer/m2-bert-80M-32k-retrieval\n",
-              "- metadata:\n",
-              "    embedding_dimension: 384\n",
-              "  model_id: all-MiniLM-L6-v2\n",
-              "  model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n",
-              "  - embedding\n",
-              "  provider_id: sentence-transformers\n",
-              "  provider_model_id: null\n",
-              "providers:\n",
-              "  agents:\n",
-              "  - config:\n",
-              "      persistence_store:\n",
-              "        db_path: /Users/xiyan/.llama/distributions/together/agents_store.db\n",
-              "        namespace: null\n",
-              "        type: sqlite\n",
-              "    provider_id: meta-reference\n",
-              "    provider_type: inline::meta-reference\n",
-              "  datasetio:\n",
-              "  - config: {}\n",
-              "    provider_id: huggingface\n",
-              "    provider_type: remote::huggingface\n",
-              "  - config: {}\n",
-              "    provider_id: localfs\n",
-              "    provider_type: inline::localfs\n",
-              "  eval:\n",
-              "  - config: {}\n",
-              "    provider_id: meta-reference\n",
-              "    provider_type: inline::meta-reference\n",
-              "  inference:\n",
-              "  - config:\n",
-              "      api_key: '********'\n",
-              "      url: https://api.together.xyz/v1\n",
-              "    provider_id: together\n",
-              "    provider_type: remote::together\n",
-              "  - config: {}\n",
-              "    provider_id: sentence-transformers\n",
-              "    provider_type: inline::sentence-transformers\n",
-              "  safety:\n",
-              "  - config: {}\n",
-              "    provider_id: llama-guard\n",
-              "    provider_type: inline::llama-guard\n",
-              "  scoring:\n",
-              "  - config: {}\n",
-              "    provider_id: basic\n",
-              "    provider_type: inline::basic\n",
-              "  - config: {}\n",
-              "    provider_id: llm-as-judge\n",
-              "    provider_type: inline::llm-as-judge\n",
-              "  - config:\n",
-              "      openai_api_key: '********'\n",
-              "    provider_id: braintrust\n",
-              "    provider_type: inline::braintrust\n",
-              "  telemetry:\n",
-              "  - config:\n",
-              "      service_name: llama-stack\n",
-              "      sinks: sqlite\n",
-              "      sqlite_db_path: /Users/xiyan/.llama/distributions/together/trace_store.db\n",
-              "    provider_id: meta-reference\n",
-              "    provider_type: inline::meta-reference\n",
-              "  tool_runtime:\n",
-              "  - config:\n",
-              "      api_key: '********'\n",
-              "      max_results: 3\n",
-              "    provider_id: brave-search\n",
-              "    provider_type: remote::brave-search\n",
-              "  - config:\n",
-              "      api_key: '********'\n",
-              "      max_results: 3\n",
-              "    provider_id: tavily-search\n",
-              "    provider_type: remote::tavily-search\n",
-              "  - config: {}\n",
-              "    provider_id: code-interpreter\n",
-              "    provider_type: inline::code-interpreter\n",
-              "  - config: {}\n",
-              "    provider_id: rag-runtime\n",
-              "    provider_type: inline::rag-runtime\n",
-              "  - config: {}\n",
-              "    provider_id: model-context-protocol\n",
-              "    provider_type: remote::model-context-protocol\n",
-              "  - config: {}\n",
-              "    provider_id: wolfram-alpha\n",
-              "    provider_type: remote::wolfram-alpha\n",
-              "  vector_io:\n",
-              "  - config:\n",
-              "      kvstore:\n",
-              "        db_path: /Users/xiyan/.llama/distributions/together/faiss_store.db\n",
-              "        namespace: null\n",
-              "        type: sqlite\n",
-              "    provider_id: faiss\n",
-              "    provider_type: inline::faiss\n",
-              "scoring_fns: []\n",
-              "server:\n",
-              "  port: 8321\n",
-              "  tls_certfile: null\n",
-              "  tls_keyfile: null\n",
-              "shields:\n",
-              "- params: null\n",
-              "  provider_id: null\n",
-              "  provider_shield_id: null\n",
-              "  shield_id: meta-llama/Llama-Guard-3-8B\n",
-              "tool_groups:\n",
-              "- args: null\n",
-              "  mcp_endpoint: null\n",
-              "  provider_id: tavily-search\n",
-              "  toolgroup_id: builtin::websearch\n",
-              "- args: null\n",
-              "  mcp_endpoint: null\n",
-              "  provider_id: rag-runtime\n",
-              "  toolgroup_id: builtin::rag\n",
-              "- args: null\n",
-              "  mcp_endpoint: null\n",
-              "  provider_id: code-interpreter\n",
-              "  toolgroup_id: builtin::code_interpreter\n",
-              "- args: null\n",
-              "  mcp_endpoint: null\n",
-              "  provider_id: wolfram-alpha\n",
-              "  toolgroup_id: builtin::wolfram_alpha\n",
-              "vector_dbs: []\n",
-              "version: '2'\n",
-              "\n",
-              "
\n" - ], - "text/plain": [ - "apis:\n", - "- agents\n", - "- datasetio\n", - "- eval\n", - "- inference\n", - "- safety\n", - "- scoring\n", - "- telemetry\n", - "- tool_runtime\n", - "- vector_io\n", - "benchmarks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "container_image: null\n", - "datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "image_name: together\n", - "metadata_store:\n", - " db_path: \u001b[35m/Users/xiyan/.llama/distributions/together/\u001b[0m\u001b[95mregistry.db\u001b[0m\n", - " namespace: null\n", - " type: sqlite\n", - "models:\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-8B-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-8B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.1\u001b[0m-8B-Instruct\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-8B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-70B-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-70B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.1\u001b[0m-70B-Instruct\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-70B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-405B-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-405B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.1\u001b[0m-405B-Instruct-FP8\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-\u001b[1;36m3.1\u001b[0m-405B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-3B-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-3B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-3B-Instruct\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-3B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-11B-Vision-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-11B-Vision-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-11B-Vision-Instruct\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-11B-Vision-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-90B-Vision-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-90B-Vision-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-90B-Vision-Instruct\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.2\u001b[0m-90B-Vision-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.3\u001b[0m-70B-Instruct-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.3\u001b[0m-70B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-\u001b[1;36m3.3\u001b[0m-70B-Instruct\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-\u001b[1;36m3.3\u001b[0m-70B-Instruct-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Meta-Llama-Guard-\u001b[1;36m3\u001b[0m-8B\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-Guard-\u001b[1;36m3\u001b[0m-8B\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-Guard-\u001b[1;36m3\u001b[0m-8B\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Meta-Llama-Guard-\u001b[1;36m3\u001b[0m-8B\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-Guard-\u001b[1;36m3\u001b[0m-11B-Vision-Turbo\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-Guard-\u001b[1;36m3\u001b[0m-11B-Vision-Turbo\n", - "- metadata: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " model_id: meta-llama/Llama-Guard-\u001b[1;36m3\u001b[0m-11B-Vision\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - llm\n", - " provider_id: together\n", - " provider_model_id: meta-llama/Llama-Guard-\u001b[1;36m3\u001b[0m-11B-Vision-Turbo\n", - "- metadata:\n", - " context_length: \u001b[1;36m8192\u001b[0m\n", - " embedding_dimension: \u001b[1;36m768\u001b[0m\n", - " model_id: togethercomputer/m2-bert-80M-8k-retrieval\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - embedding\n", - " provider_id: together\n", - " provider_model_id: togethercomputer/m2-bert-80M-8k-retrieval\n", - "- metadata:\n", - " context_length: \u001b[1;36m32768\u001b[0m\n", - " embedding_dimension: \u001b[1;36m768\u001b[0m\n", - " model_id: togethercomputer/m2-bert-80M-32k-retrieval\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - embedding\n", - " provider_id: together\n", - " provider_model_id: togethercomputer/m2-bert-80M-32k-retrieval\n", - "- metadata:\n", - " embedding_dimension: \u001b[1;36m384\u001b[0m\n", - " model_id: all-MiniLM-L6-v2\n", - " model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType\n", - " - embedding\n", - " provider_id: sentence-transformers\n", - " provider_model_id: null\n", - "providers:\n", - " agents:\n", - " - config:\n", - " persistence_store:\n", - " db_path: \u001b[35m/Users/xiyan/.llama/distributions/together/\u001b[0m\u001b[95magents_store.db\u001b[0m\n", - " namespace: null\n", - " type: sqlite\n", - " provider_id: meta-reference\n", - " provider_type: inline::meta-reference\n", - " datasetio:\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: huggingface\n", - " provider_type: remote::huggingface\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: localfs\n", - " provider_type: inline::localfs\n", - " eval:\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: meta-reference\n", - " provider_type: inline::meta-reference\n", - " inference:\n", - " - config:\n", - " api_key: \u001b[32m'********'\u001b[0m\n", - " url: \u001b[4;94mhttps://api.together.xyz/v1\u001b[0m\n", - " provider_id: together\n", - " provider_type: remote::together\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: sentence-transformers\n", - " provider_type: inline::sentence-transformers\n", - " safety:\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: llama-guard\n", - " provider_type: inline::llama-guard\n", - " scoring:\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: basic\n", - " provider_type: inlin\u001b[1;92me::ba\u001b[0msic\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: llm-as-judge\n", - " provider_type: inline::llm-as-judge\n", - " - config:\n", - " openai_api_key: \u001b[32m'********'\u001b[0m\n", - " provider_id: braintrust\n", - " provider_type: inlin\u001b[1;92me::b\u001b[0mraintrust\n", - " telemetry:\n", - " - config:\n", - " service_name: llama-stack\n", - " sinks: sqlite\n", - " sqlite_db_path: \u001b[35m/Users/xiyan/.llama/distributions/together/\u001b[0m\u001b[95mtrace_store.db\u001b[0m\n", - " provider_id: meta-reference\n", - " provider_type: inline::meta-reference\n", - " tool_runtime:\n", - " - config:\n", - " api_key: \u001b[32m'********'\u001b[0m\n", - " max_results: \u001b[1;36m3\u001b[0m\n", - " provider_id: brave-search\n", - " provider_type: remot\u001b[1;92me::b\u001b[0mrave-search\n", - " - config:\n", - " api_key: \u001b[32m'********'\u001b[0m\n", - " max_results: \u001b[1;36m3\u001b[0m\n", - " provider_id: tavily-search\n", - " provider_type: remote::tavily-search\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: code-interpreter\n", - " provider_type: inlin\u001b[1;92me::c\u001b[0mode-interpreter\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: rag-runtime\n", - " provider_type: inline::rag-runtime\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: model-context-protocol\n", - " provider_type: remote::model-context-protocol\n", - " - config: \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m\n", - " provider_id: wolfram-alpha\n", - " provider_type: remote::wolfram-alpha\n", - " vector_io:\n", - " - config:\n", - " kvstore:\n", - " db_path: \u001b[35m/Users/xiyan/.llama/distributions/together/\u001b[0m\u001b[95mfaiss_store.db\u001b[0m\n", - " namespace: null\n", - " type: sqlite\n", - " provider_id: faiss\n", - " provider_type: inlin\u001b[1;92me::fa\u001b[0miss\n", - "scoring_fns: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "server:\n", - " port: \u001b[1;36m8321\u001b[0m\n", - " tls_certfile: null\n", - " tls_keyfile: null\n", - "shields:\n", - "- params: null\n", - " provider_id: null\n", - " provider_shield_id: null\n", - " shield_id: meta-llama/Llama-Guard-\u001b[1;36m3\u001b[0m-8B\n", - "tool_groups:\n", - "- args: null\n", - " mcp_endpoint: null\n", - " provider_id: tavily-search\n", - " toolgroup_id: builtin::websearch\n", - "- args: null\n", - " mcp_endpoint: null\n", - " provider_id: rag-runtime\n", - " toolgroup_id: builtin::rag\n", - "- args: null\n", - " mcp_endpoint: null\n", - " provider_id: code-interpreter\n", - " toolgroup_id: builtin::code_interpreter\n", - "- args: null\n", - " mcp_endpoint: null\n", - " provider_id: wolfram-alpha\n", - " toolgroup_id: builtin::wolfram_alpha\n", - "vector_dbs: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "version: \u001b[32m'2'\u001b[0m\n", - "\n" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ @@ -860,9 +402,36 @@ " api_key = input(f\"{key} environment variable is not set. Please enter your API key: \")\n", " os.environ[key] = api_key\n", "\n", - "from llama_stack.distribution.library_client import LlamaStackAsLibraryClient\n", - "client = LlamaStackAsLibraryClient(\"together\", provider_data = {\"tavily_search_api_key\": os.environ['TAVILY_SEARCH_API_KEY']})\n", - "_ = client.initialize()" + "from llama_stack_client import LlamaStackClient\n", + "\n", + "client = LlamaStackClient(\n", + " base_url=\"http://0.0.0.0:8321\", \n", + " provider_data = {\n", + " \"tavily_search_api_key\": os.environ['TAVILY_SEARCH_API_KEY'], \n", + " \"together_api_key\": os.environ['TOGETHER_API_KEY']\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "635a7a6f", + "metadata": {}, + "source": [ + "In production settings, instead of pointing to localhost you could work with one of our partners that host a llama stack endpoint or host your own custom version. \n", + "\n", + "That would only require you to change the endpoint without changing application code. For eg. \n", + "```\n", + "client = LlamaStackClient(\n", + " base_url=\"https://llama-stack.together.ai\",\n", + " provider_data = {\n", + " \"together_api_key\": XXXX\n", + " }\n", + ")\n", + "```\n", + "\n", + "Now that we have completed the setup and configuration, let's start exploring the capabilities of Llama Stack! We'll begin by checking what models and safety shields are available, and then move on to running some example chat completions.\n", + "\n" ] }, { @@ -895,16 +464,27 @@ "output_type": "stream", "text": [ "Available models:\n", - "all-MiniLM-L6-v2 (provider's alias: all-MiniLM-L6-v2) \n", - "meta-llama/Llama-3.1-405B-Instruct-FP8 (provider's alias: meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo) \n", - "meta-llama/Llama-3.1-70B-Instruct (provider's alias: meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo) \n", - "meta-llama/Llama-3.1-8B-Instruct (provider's alias: meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo) \n", - "meta-llama/Llama-3.2-11B-Vision-Instruct (provider's alias: meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo) \n", - "meta-llama/Llama-3.2-3B-Instruct (provider's alias: meta-llama/Llama-3.2-3B-Instruct-Turbo) \n", - "meta-llama/Llama-3.2-90B-Vision-Instruct (provider's alias: meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo) \n", - "meta-llama/Llama-3.3-70B-Instruct (provider's alias: meta-llama/Llama-3.3-70B-Instruct-Turbo) \n", - "meta-llama/Llama-Guard-3-11B-Vision (provider's alias: meta-llama/Llama-Guard-3-11B-Vision-Turbo) \n", - "meta-llama/Llama-Guard-3-8B (provider's alias: meta-llama/Meta-Llama-Guard-3-8B) \n", + "- all-MiniLM-L6-v2\n", + "- meta-llama/Llama-3.1-405B-Instruct-FP8\n", + "- meta-llama/Llama-3.1-70B-Instruct\n", + "- meta-llama/Llama-3.1-8B-Instruct\n", + "- meta-llama/Llama-3.2-11B-Vision-Instruct\n", + "- meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo\n", + "- meta-llama/Llama-3.2-3B-Instruct\n", + "- meta-llama/Llama-3.2-3B-Instruct-Turbo\n", + "- meta-llama/Llama-3.2-90B-Vision-Instruct\n", + "- meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo\n", + "- meta-llama/Llama-3.3-70B-Instruct\n", + "- meta-llama/Llama-3.3-70B-Instruct-Turbo\n", + "- meta-llama/Llama-Guard-3-11B-Vision\n", + "- meta-llama/Llama-Guard-3-11B-Vision-Turbo\n", + "- meta-llama/Llama-Guard-3-8B\n", + "- meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo\n", + "- meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\n", + "- meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo\n", + "- meta-llama/Meta-Llama-Guard-3-8B\n", + "- togethercomputer/m2-bert-80M-32k-retrieval\n", + "- togethercomputer/m2-bert-80M-8k-retrieval\n", "----\n", "Available shields (safety models):\n", "meta-llama/Llama-Guard-3-8B\n", @@ -917,7 +497,7 @@ "\n", "print(\"Available models:\")\n", "for m in client.models.list():\n", - " print(f\"{m.identifier} (provider's alias: {m.provider_resource_id}) \")\n", + " print(f\"- {m.identifier}\")\n", "\n", "print(\"----\")\n", "print(\"Available shields (safety models):\")\n", @@ -926,48 +506,6 @@ "print(\"----\")\n" ] }, - { - "cell_type": "markdown", - "id": "E7x0QB5QwDcw", - "metadata": { - "id": "E7x0QB5QwDcw" - }, - "source": [ - "### 1.6. Pick the model\n", - "\n", - "We will use Llama3.1-70B-Instruct for our examples." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "LINBvv8lwTJh", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 35 - }, - "id": "LINBvv8lwTJh", - "outputId": "8b79cb3b-d690-472f-aad1-2ea8553de701" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'meta-llama/Llama-3.1-70B-Instruct'" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model_id = \"meta-llama/Llama-3.3-70B-Instruct\"\n", - "\n", - "model_id\n" - ] - }, { "cell_type": "markdown", "id": "86366383", @@ -975,14 +513,14 @@ "id": "86366383" }, "source": [ - "### 1.7. Run a simple chat completion\n", + "### 1.6. Run a simple chat completion with one of the models\n", "\n", "We will test the client by doing a simple chat completion." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "77c29dba", "metadata": { "colab": { @@ -996,14 +534,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "Here is a two-sentence poem about a llama:\n", - "\n", - "With gentle eyes and a soft, fuzzy face,\n", - "The llama roams, a peaceful, gentle pace.\n" + "With gentle eyes and a soft, fuzzy face, the llama roams the Andes with a peaceful, gentle pace. Its long neck bends as it grazes with glee, a symbol of serenity in a world wild and free.\n" ] } ], "source": [ + "model_id = \"meta-llama/Llama-3.3-70B-Instruct\"\n", + "\n", "response = client.inference.chat_completion(\n", " model_id=model_id,\n", " messages=[\n", @@ -1022,14 +559,14 @@ "id": "8cf0d555" }, "source": [ - "### 1.8. Have a conversation\n", + "### 1.7. Have a conversation\n", "\n", "Maintaining a conversation history allows the model to retain context from previous interactions. Use a list to accumulate messages, enabling continuity throughout the chat session." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "3fdf9df6", "metadata": { "id": "3fdf9df6" @@ -1039,18 +576,30 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[36m> Response: The most famous Prime Minister of England during World War 2 was Winston Churchill. He served as the Prime Minister of the United Kingdom from 1940 to 1945 and again from 1951 to 1955. Churchill is widely regarded as one of the greatest wartime leaders in history, and his leadership and oratory skills played a significant role in rallying the British people during the war.\n", + "\u001b[36m> Response: The most famous Prime Minister of England during World War II was undoubtedly Winston Churchill. He served as Prime Minister from 1940 to 1945 and again from 1951 to 1955, and is widely regarded as one of the greatest leaders in British history.\n", "\n", - "Churchill's famous speeches, such as \"We shall fight on the beaches\" and \"Their finest hour,\" helped to boost British morale and resistance against the Nazi threat. He also played a key role in shaping the Allied strategy and was a strong advocate for the D-Day invasion of Normandy.\n", + "Churchill played a crucial role in rallying the British people during the war, and his oratory skills and leadership helped to boost morale and resistance against the Nazi threat. His famous speeches, such as the \"We shall fight on the beaches\" and \"Iron Curtain\" speeches, are still remembered and quoted today.\n", "\n", - "Churchill's leadership during World War 2 has become iconic, and he remains one of the most revered and celebrated figures in British history.\u001b[0m\n", - "\u001b[36m> Response: Winston Churchill's most famous quote is:\n", + "Churchill's leadership during World War II was marked by his unwavering determination to defeat Nazi Germany, and he worked closely with other Allied leaders, including US President Franklin D. Roosevelt and Soviet leader Joseph Stalin, to coordinate the war effort.\n", + "\n", + "Churchill's legacy extends far beyond his wartime leadership, and he is remembered for his many contributions to British politics, literature, and culture. He was a prolific writer and painter, and was awarded the Nobel Prize in Literature in 1953.\n", + "\n", + "Overall, Winston Churchill is widely regarded as one of the most famous and influential Prime Ministers in British history, and his leadership during World War II remains an iconic and enduring symbol of British resilience and determination.\u001b[0m\n", + "\u001b[36m> Response: Winston Churchill had many famous quotes, but one of his most iconic and enduring quotes is:\n", "\n", "\"We shall fight on the beaches, we shall fight on the landing grounds, we shall fight in the fields and in the streets, we shall fight in the hills; we shall never surrender.\"\n", "\n", - "This quote is from his speech to the House of Commons on June 4, 1940, during the early stages of World War 2, when Nazi Germany was threatening to invade Britain. The speech is known as the \"We Shall Fight on the Beaches\" speech, and it is considered one of the most iconic and inspiring speeches in history.\n", + "This quote is from his speech to the House of Commons on June 4, 1940, during the early stages of World War II, when Nazi Germany was threatening to invade Britain. The speech is known as the \"We Shall Fight on the Beaches\" speech, and it is considered one of the most famous and inspiring speeches in history.\n", "\n", - "In the speech, Churchill rallied the British people to prepare for the possibility of a German invasion, and he famously declared that even if the British Empire were to last for a thousand years, the bravery and determination of the British people during this time would be remembered as their \"finest hour.\"\u001b[0m\n" + "In this speech, Churchill rallied the British people to stand strong against the Nazi threat, and his words helped to boost morale and resistance. The quote has since become a symbol of British determination and resilience, and is often referenced and parodied in popular culture.\n", + "\n", + "Other notable quotes from Churchill include:\n", + "\n", + "* \"Blood, toil, tears, and sweat\" (from his first speech as Prime Minister in 1940)\n", + "* \"An iron curtain has descended across the continent\" (from his speech in 1946, referring to the Soviet Union's dominance in Eastern Europe)\n", + "* \"Never was so much owed by so many to so few\" (from his speech in 1940, referring to the bravery of the Royal Air Force during the Battle of Britain)\n", + "\n", + "But \"We shall fight on the beaches\" remains his most famous and enduring quote.\u001b[0m\n" ] } ], @@ -1104,7 +653,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "9496f75c", "metadata": { "colab": { @@ -1118,7 +667,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[36m> Response: Hello, it's nice to meet you. Is there something I can help you with or would you like to chat?\u001b[0m\n", + "\u001b[36m> Response: Fuzzy code abides\n", + "Llama's gentle syntax\n", + "Wisdom in the stack\u001b[0m\n", "\u001b[33mEnding conversation. Goodbye!\u001b[0m\n" ] } @@ -1169,7 +720,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "d119026e", "metadata": { "colab": { @@ -1183,24 +734,24 @@ "name": "stdout", "output_type": "stream", "text": [ - "User> Write me a sonnet about llama green\n", + "User> Write me a sonnet about llama\n", "\u001b[36mAssistant> \u001b[0m\u001b[33mIn\u001b[0m\u001b[33m And\u001b[0m\u001b[33mean\u001b[0m\u001b[33m high\u001b[0m\u001b[33mlands\u001b[0m\u001b[33m,\u001b[0m\u001b[33m where\u001b[0m\u001b[33m the\u001b[0m\u001b[33m air\u001b[0m\u001b[33m is\u001b[0m\u001b[33m thin\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mA\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m creature\u001b[0m\u001b[33m ro\u001b[0m\u001b[33mams\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m steps\u001b[0m\u001b[33m serene\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m its\u001b[0m\u001b[33m soft\u001b[0m\u001b[33m and\u001b[0m\u001b[33m wool\u001b[0m\u001b[33mly\u001b[0m\u001b[33m skin\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mA\u001b[0m\u001b[33m symbol\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m region\u001b[0m\u001b[33m's\u001b[0m\u001b[33m myst\u001b[0m\u001b[33mic\u001b[0m\u001b[33m she\u001b[0m\u001b[33men\u001b[0m\u001b[33m.\n", + "\u001b[0m\u001b[33mA\u001b[0m\u001b[33m creature\u001b[0m\u001b[33m ro\u001b[0m\u001b[33mams\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m,\u001b[0m\u001b[33m curious\u001b[0m\u001b[33m eyes\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m,\u001b[0m\u001b[33m soft\u001b[0m\u001b[33m and\u001b[0m\u001b[33m silent\u001b[0m\u001b[33m,\u001b[0m\u001b[33m steps\u001b[0m\u001b[33m within\u001b[0m\u001b[33m\n", + "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m mist\u001b[0m\u001b[33my\u001b[0m\u001b[33m dawn\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m fur\u001b[0m\u001b[33m of\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m guise\u001b[0m\u001b[33m.\n", "\n", - "\u001b[0m\u001b[33mIts\u001b[0m\u001b[33m eyes\u001b[0m\u001b[33m,\u001b[0m\u001b[33m like\u001b[0m\u001b[33m darkest\u001b[0m\u001b[33m night\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m wisdom\u001b[0m\u001b[33m shine\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mReflect\u001b[0m\u001b[33ming\u001b[0m\u001b[33m ancient\u001b[0m\u001b[33m knowledge\u001b[0m\u001b[33m,\u001b[0m\u001b[33m passed\u001b[0m\u001b[33m down\u001b[0m\u001b[33m line\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mIts\u001b[0m\u001b[33m ears\u001b[0m\u001b[33m,\u001b[0m\u001b[33m like\u001b[0m\u001b[33m satellite\u001b[0m\u001b[33m dishes\u001b[0m\u001b[33m,\u001b[0m\u001b[33m fine\u001b[0m\u001b[33m and\u001b[0m\u001b[33m bright\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mListening\u001b[0m\u001b[33m to\u001b[0m\u001b[33m the\u001b[0m\u001b[33m whispers\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m wind\u001b[0m\u001b[33m's\u001b[0m\u001b[33m design\u001b[0m\u001b[33m.\n", + "\u001b[0m\u001b[33mIts\u001b[0m\u001b[33m neck\u001b[0m\u001b[33m,\u001b[0m\u001b[33m a\u001b[0m\u001b[33m slender\u001b[0m\u001b[33m column\u001b[0m\u001b[33m,\u001b[0m\u001b[33m strong\u001b[0m\u001b[33m and\u001b[0m\u001b[33m fine\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mSupport\u001b[0m\u001b[33ms\u001b[0m\u001b[33m a\u001b[0m\u001b[33m head\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m ears\u001b[0m\u001b[33m of\u001b[0m\u001b[33m alert\u001b[0m\u001b[33m design\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mIt\u001b[0m\u001b[33m watches\u001b[0m\u001b[33m,\u001b[0m\u001b[33m wary\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m a\u001b[0m\u001b[33m quiet\u001b[0m\u001b[33m mind\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mAs\u001b[0m\u001b[33m humans\u001b[0m\u001b[33m pass\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m footsteps\u001b[0m\u001b[33m left\u001b[0m\u001b[33m behind\u001b[0m\u001b[33m.\n", "\n", - "\u001b[0m\u001b[33mWith\u001b[0m\u001b[33m steps\u001b[0m\u001b[33m that\u001b[0m\u001b[33m barely\u001b[0m\u001b[33m touch\u001b[0m\u001b[33m the\u001b[0m\u001b[33m mountain\u001b[0m\u001b[33m ground\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mIt\u001b[0m\u001b[33m gl\u001b[0m\u001b[33mides\u001b[0m\u001b[33m,\u001b[0m\u001b[33m a\u001b[0m\u001b[33m ghost\u001b[0m\u001b[33mly\u001b[0m\u001b[33m appar\u001b[0m\u001b[33mition\u001b[0m\u001b[33m,\u001b[0m\u001b[33m sound\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mIts\u001b[0m\u001b[33m soft\u001b[0m\u001b[33m hum\u001b[0m\u001b[33m,\u001b[0m\u001b[33m a\u001b[0m\u001b[33m l\u001b[0m\u001b[33mull\u001b[0m\u001b[33maby\u001b[0m\u001b[33m,\u001b[0m\u001b[33m that\u001b[0m\u001b[33m soo\u001b[0m\u001b[33mthes\u001b[0m\u001b[33m the\u001b[0m\u001b[33m soul\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mAs\u001b[0m\u001b[33m it\u001b[0m\u001b[33m travers\u001b[0m\u001b[33mes\u001b[0m\u001b[33m the\u001b[0m\u001b[33m rugged\u001b[0m\u001b[33m,\u001b[0m\u001b[33m rocky\u001b[0m\u001b[33m role\u001b[0m\u001b[33m.\n", + "\u001b[0m\u001b[33mBut\u001b[0m\u001b[33m when\u001b[0m\u001b[33m it\u001b[0m\u001b[33m senses\u001b[0m\u001b[33m danger\u001b[0m\u001b[33m,\u001b[0m\u001b[33m or\u001b[0m\u001b[33m feels\u001b[0m\u001b[33m fright\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mIt\u001b[0m\u001b[33m lets\u001b[0m\u001b[33m out\u001b[0m\u001b[33m a\u001b[0m\u001b[33m loud\u001b[0m\u001b[33m,\u001b[0m\u001b[33m piercing\u001b[0m\u001b[33m,\u001b[0m\u001b[33m warning\u001b[0m\u001b[33m cry\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mA\u001b[0m\u001b[33m sound\u001b[0m\u001b[33m that\u001b[0m\u001b[33m echoes\u001b[0m\u001b[33m,\u001b[0m\u001b[33m through\u001b[0m\u001b[33m the\u001b[0m\u001b[33m mountain\u001b[0m\u001b[33m's\u001b[0m\u001b[33m night\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mAnd\u001b[0m\u001b[33m sends\u001b[0m\u001b[33m a\u001b[0m\u001b[33m sh\u001b[0m\u001b[33miver\u001b[0m\u001b[33m,\u001b[0m\u001b[33m through\u001b[0m\u001b[33m the\u001b[0m\u001b[33m passer\u001b[0m\u001b[33mby\u001b[0m\u001b[33m.\n", "\n", - "\u001b[0m\u001b[33mAnd\u001b[0m\u001b[33m when\u001b[0m\u001b[33m it\u001b[0m\u001b[33m stops\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m looks\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m gaze\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mIt\u001b[0m\u001b[33m seems\u001b[0m\u001b[33m to\u001b[0m\u001b[33m hold\u001b[0m\u001b[33m the\u001b[0m\u001b[33m secrets\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m And\u001b[0m\u001b[33mean\u001b[0m\u001b[33m ways\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n" + "\u001b[0m\u001b[33mYet\u001b[0m\u001b[33m,\u001b[0m\u001b[33m in\u001b[0m\u001b[33m its\u001b[0m\u001b[33m calm\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m peaceful\u001b[0m\u001b[33m,\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m way\u001b[0m\u001b[33m,\n", + "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m charms\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m wins\u001b[0m\u001b[33m the\u001b[0m\u001b[33m heart\u001b[0m\u001b[33m's\u001b[0m\u001b[33m sweet\u001b[0m\u001b[33m sway\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n" ] } ], @@ -1208,7 +759,7 @@ "from llama_stack_client import InferenceEventLogger\n", "\n", "message = {\"role\": \"user\", \"content\": \"Write me a sonnet about llama\"}\n", - "print(f'User> {message[\"content\"]}', \"green\")\n", + "print(f'User> {message[\"content\"]}')\n", "\n", "response = client.inference.chat_completion(\n", " messages=[message],\n", @@ -1235,7 +786,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "axdQIRaJCYAV", "metadata": { "colab": { @@ -1249,19 +800,11 @@ { "data": { "text/html": [ - "
CompletionResponse(\n",
-              "content='{\"name\": \"Michael Jordan\", \"year_born\": \"1963\", \"year_retired\": \"2003\"}',\n",
-              "stop_reason='end_of_turn',\n",
-              "logprobs=None\n",
-              ")\n",
+              "
Output(name='Michael Jordan', year_born='1963', year_retired='2003')\n",
               "
\n" ], "text/plain": [ - "\u001b[1;35mCompletionResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"name\": \"Michael Jordan\", \"year_born\": \"1963\", \"year_retired\": \"2003\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mlogprobs\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" + "\u001b[1;35mOutput\u001b[0m\u001b[1m(\u001b[0m\u001b[33mname\u001b[0m=\u001b[32m'Michael Jordan'\u001b[0m, \u001b[33myear_born\u001b[0m=\u001b[32m'1963'\u001b[0m, \u001b[33myear_retired\u001b[0m=\u001b[32m'2003'\u001b[0m\u001b[1m)\u001b[0m\n" ] }, "metadata": {}, @@ -1295,7 +838,7 @@ " },\n", ")\n", "\n", - "pprint(response)\n" + "pprint(Output.model_validate_json(response.content))\n" ] }, { @@ -1312,7 +855,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "sUJKJxvAFCaI", "metadata": { "colab": { @@ -1491,7 +1034,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "MpMXiMCv97X5", "metadata": { "colab": { @@ -1582,6 +1125,33 @@ }, "metadata": {}, "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
ToolGroup(\n",
+              "identifier='builtin::wolfram_alpha',\n",
+              "provider_id='wolfram-alpha',\n",
+              "provider_resource_id='builtin::wolfram_alpha',\n",
+              "type='tool_group',\n",
+              "args=None,\n",
+              "mcp_endpoint=None\n",
+              ")\n",
+              "
\n" + ], + "text/plain": [ + "\u001b[1;35mToolGroup\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'builtin::wolfram_alpha'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'wolfram-alpha'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'builtin::wolfram_alpha'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool_group'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33margs\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mmcp_endpoint\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -1608,7 +1178,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "WS8Gu5b0APHs", "metadata": { "colab": { @@ -1623,11 +1193,11 @@ "output_type": "stream", "text": [ "\u001b[32mUser> Hello\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[33mHello\u001b[0m\u001b[33m.\u001b[0m\u001b[33m How\u001b[0m\u001b[33m can\u001b[0m\u001b[33m I\u001b[0m\u001b[33m assist\u001b[0m\u001b[33m you\u001b[0m\u001b[33m today\u001b[0m\u001b[33m?\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33mHello\u001b[0m\u001b[33m!\u001b[0m\u001b[33m It\u001b[0m\u001b[33m's\u001b[0m\u001b[33m nice\u001b[0m\u001b[33m to\u001b[0m\u001b[33m meet\u001b[0m\u001b[33m you\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Is\u001b[0m\u001b[33m there\u001b[0m\u001b[33m something\u001b[0m\u001b[33m I\u001b[0m\u001b[33m can\u001b[0m\u001b[33m help\u001b[0m\u001b[33m you\u001b[0m\u001b[33m with\u001b[0m\u001b[33m or\u001b[0m\u001b[33m would\u001b[0m\u001b[33m you\u001b[0m\u001b[33m like\u001b[0m\u001b[33m to\u001b[0m\u001b[33m chat\u001b[0m\u001b[33m?\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[30m\u001b[0m\u001b[32mUser> Which teams played in the NBA western conference finals of 2024\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mN\u001b[0m\u001b[36mBA\u001b[0m\u001b[36m Western\u001b[0m\u001b[36m Conference\u001b[0m\u001b[36m Finals\u001b[0m\u001b[36m \u001b[0m\u001b[36m202\u001b[0m\u001b[36m4\u001b[0m\u001b[36m teams\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mN\u001b[0m\u001b[36mBA\u001b[0m\u001b[36m Western\u001b[0m\u001b[36m Conference\u001b[0m\u001b[36m Finals\u001b[0m\u001b[36m \u001b[0m\u001b[36m202\u001b[0m\u001b[36m4\u001b[0m\u001b[36m teams\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'NBA Western Conference Finals 2024 teams'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\u010di\\u0107 (635) TRB: Luka Don\\u010di\\u0107 (208) AST: Luka Don\\u010di\\u0107 (178) WS: Derrick White (2.9) More playoffs info\", \"score\": 0.9310187, \"raw_content\": null}, {\"title\": \"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\", \"url\": \"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\", \"content\": \"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\", \"score\": 0.8914433, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\", \"score\": 0.8884594, \"raw_content\": null}, {\"title\": \"NBA Conference Finals Schedule: Full List of Games & Results\", \"url\": \"https://www.si.com/nba/nba-conference-finals-schedule-full-list-of-games-results\", \"content\": \"The 2024 NBA conference finals matchups are set. Here's the schedule for all the games. ... Western Conference First Round (1) Oklahoma City Thunder def. (8) New Orleans Pelicans in 4 games\", \"score\": 0.850382, \"raw_content\": null}, {\"title\": \"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\", \"url\": \"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\", \"content\": \"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\", \"score\": 0.8194462, \"raw_content\": null}]}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\u00a0Reference\\u202f\\u00ae Baseball Football (college) Basketball (college) Hockey F\\u00fatbol Blog Stathead\\u202f\\u00ae Immaculate Grid\\u202f\\u00ae\", \"score\": 0.89030397, \"raw_content\": null}, {\"title\": \"NBA Standings - 2024-25 season - ESPN\", \"url\": \"https://www.espn.com/nba/standings\", \"content\": \"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children's Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries ('PENN').\", \"score\": 0.83549726, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) | NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: 'This is special, coming from the West' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.75312227, \"raw_content\": null}, {\"title\": \"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\", \"url\": \"https://www.nba.com/playoffs/2024?os=wtmbloozowcj&ref=app\", \"content\": \"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 (Ep. 25) Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston's NBA-record 18th championship. WE DID ITTTT!' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\", \"score\": 0.63234437, \"raw_content\": null}, {\"title\": \"2025 NBA Playoffs: Standings, bracket and clinching updates\", \"url\": \"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\", \"content\": \"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\"Access Content\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\", \"score\": 0.13435538, \"raw_content\": null}]}\u001b[0m\n", "\u001b[33minference> \u001b[0m\u001b[33mThe\u001b[0m\u001b[33m teams\u001b[0m\u001b[33m that\u001b[0m\u001b[33m played\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m NBA\u001b[0m\u001b[33m Western\u001b[0m\u001b[33m Conference\u001b[0m\u001b[33m Finals\u001b[0m\u001b[33m of\u001b[0m\u001b[33m \u001b[0m\u001b[33m202\u001b[0m\u001b[33m4\u001b[0m\u001b[33m were\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Dallas\u001b[0m\u001b[33m Mavericks\u001b[0m\u001b[33m and\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Minnesota\u001b[0m\u001b[33m Timber\u001b[0m\u001b[33mw\u001b[0m\u001b[33molves\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[30m\u001b[0m" ] @@ -1639,7 +1209,7 @@ "\n", "agent = Agent(\n", " client, \n", - " model=model_id,\n", + " model=\"meta-llama/Llama-3.3-70B-Instruct\",\n", " instructions=\"You are a helpful assistant. Use websearch tool to help answer questions.\",\n", " tools=[\"builtin::websearch\"],\n", ")\n", @@ -1753,56 +1323,19 @@ "outputId": "ef5f3ec4-edaf-4705-fb1b-b86659d7143c" }, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Batches: 100%|██████████| 1/1 [00:00<00:00, 1.83it/s]" - ] - }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32mUser> What are the top 5 topics that were explained? Only list succinct bullet points.\u001b[0m\n", - "\u001b[30m\u001b[0m" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n", - "Batches: 100%|██████████| 1/1 [00:00<00:00, 7.28it/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32mtool_execution> Tool:query_from_memory Args:{}\u001b[0m\n", - "\u001b[36mtool_execution> fetched 10913 bytes from memory\u001b[0m\n", - "\u001b[33minference> \u001b[0m" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33mHere\u001b[0m\u001b[33m are\u001b[0m\u001b[33m the\u001b[0m\u001b[33m top\u001b[0m\u001b[33m \u001b[0m\u001b[33m5\u001b[0m\u001b[33m topics\u001b[0m\u001b[33m that\u001b[0m\u001b[33m were\u001b[0m\u001b[33m explained\u001b[0m\u001b[33m:\n", - "\n", - "\u001b[0m\u001b[33m•\u001b[0m\u001b[33m Token\u001b[0m\u001b[33mizing\u001b[0m\u001b[33m prompt\u001b[0m\u001b[33m templates\u001b[0m\u001b[33m and\u001b[0m\u001b[33m special\u001b[0m\u001b[33m tokens\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m•\u001b[0m\u001b[33m Fine\u001b[0m\u001b[33m-t\u001b[0m\u001b[33muning\u001b[0m\u001b[33m on\u001b[0m\u001b[33m a\u001b[0m\u001b[33m custom\u001b[0m\u001b[33m chat\u001b[0m\u001b[33m dataset\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m•\u001b[0m\u001b[33m Using\u001b[0m\u001b[33m the\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m2\u001b[0m\u001b[33mChat\u001b[0m\u001b[33mTemplate\u001b[0m\u001b[33m class\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m•\u001b[0m\u001b[33m Formatting\u001b[0m\u001b[33m messages\u001b[0m\u001b[33m with\u001b[0m\u001b[33m the\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m2\u001b[0m\u001b[33mChat\u001b[0m\u001b[33mTemplate\u001b[0m\u001b[33m class\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m•\u001b[0m\u001b[33m Creating\u001b[0m\u001b[33m a\u001b[0m\u001b[33m custom\u001b[0m\u001b[33m dataset\u001b[0m\u001b[33m for\u001b[0m\u001b[33m fine\u001b[0m\u001b[33m-t\u001b[0m\u001b[33muning\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m3\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[k\u001b[0m\u001b[33mnowledge\u001b[0m\u001b[33m_search\u001b[0m\u001b[33m(query\u001b[0m\u001b[33m=\"\u001b[0m\u001b[33mtop\u001b[0m\u001b[33m \u001b[0m\u001b[33m5\u001b[0m\u001b[33m explained\u001b[0m\u001b[33m topics\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:knowledge_search Args:{'query': 'top 5 explained topics'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:knowledge_search Response:[TextContentItem(text='knowledge_search tool found 5 chunks:\\nBEGIN of knowledge_search tool results.\\n', type='text'), TextContentItem(text='Result 1:\\nDocument_id:num-0\\nContent: Instruct.\\n\\n.. _prompt_template_vs_special_tokens:\\n\\nTokenizing prompt templates & special tokens\\n--------------------------------------------\\n\\nLet\\'s say I have a sample of a single user-assistant turn accompanied with a system\\nprompt:\\n\\n.. code-block:: python\\n\\n sample = [\\n {\\n \"role\": \"system\",\\n \"content\": \"You are a helpful, respectful, and honest assistant.\",\\n },\\n {\\n \"role\": \"user\",\\n \"content\": \"Who are the most influential hip-hop artists of all time?\",\\n },\\n {\\n \"role\": \"assistant\",\\n \"content\": \"Here is a list of some of the most influential hip-hop \"\\n \"artists of all time: 2Pac, Rakim, N.W.A., Run-D.M.C., and Nas.\",\\n },\\n ]\\n\\nNow, let\\'s format this with the :class:`~torchtune.models.llama2.Llama2ChatTemplate` class and\\nsee how it gets tokenized. The Llama2ChatTemplate is an example of a **prompt template**,\\nwhich simply structures a prompt with flavor text to indicate a certain task.\\n\\n.. code-block:: python\\n\\n from torchtune.data import Llama2ChatTemplate, Message\\n\\n messages = [Message.from_dict(msg) for msg in sample]\\n formatted_messages = Llama2ChatTemplate.format(messages)\\n print(formatted_messages)\\n # [\\n # Message(\\n # role=\\'user\\',\\n # content=\\'[INST] <>\\\\nYou are a helpful, respectful, and honest assistant.\\\\n<>\\\\n\\\\nWho are the most influential hip-hop artists of all time? [/INST] \\',\\n # ...,\\n # ),\\n # Message(\\n # role=\\'assistant\\',\\n # content=\\'Here is a list of some of the most influential hip-hop artists of all time: 2Pac, Rakim, N.W.A., Run-D.M.C., and Nas.\\',\\n # ...,\\n # ),\\n # ]\\n\\nThere are also special tokens used by Llama2, which are not in the prompt template.\\nIf you look at our :class:`~torchtune.models.llama2.Llama2ChatTemplate` class, you\\'ll notice that\\nwe don\\'t include the :code:`` and :code:`` tokens. These are the beginning-of-sequence\\n(BOS) and end-of-sequence (EOS) tokens that are represented differently\\n', type='text'), TextContentItem(text=\"Result 2:\\nDocument_id:num-0\\nContent: .. _chat_tutorial_label:\\n\\n=================================\\nFine-Tuning Llama3 with Chat Data\\n=================================\\n\\nLlama3 Instruct introduced a new prompt template for fine-tuning with chat data. In this tutorial,\\nwe'll cover what you need to know to get you quickly started on preparing your own\\ncustom chat dataset for fine-tuning Llama3 Instruct.\\n\\n.. grid:: 2\\n\\n .. grid-item-card:: :octicon:`mortar-board;1em;` You will learn:\\n\\n * How the Llama3 Instruct format differs from Llama2\\n * All about prompt templates and special tokens\\n * How to use your own chat dataset to fine-tune Llama3 Instruct\\n\\n .. grid-item-card:: :octicon:`list-unordered;1em;` Prerequisites\\n\\n * Be familiar with :ref:`configuring datasets`\\n * Know how to :ref:`download Llama3 Instruct weights `\\n\\n\\nTemplate changes from Llama2 to Llama3\\n--------------------------------------\\n\\nThe Llama2 chat model requires a specific template when prompting the pre-trained\\nmodel. Since the chat model was pretrained with this prompt template, if you want to run\\ninference on the model, you'll need to use the same template for optimal performance\\non chat data. Otherwise, the model will just perform standard text completion, which\\nmay or may not align with your intended use case.\\n\\nFrom the `official Llama2 prompt\\ntemplate guide `_\\nfor the Llama2 chat model, we can see that special tags are added:\\n\\n.. code-block:: text\\n\\n [INST] <>\\n You are a helpful, respectful, and honest assistant.\\n <>\\n\\n Hi! I am a human. [/INST] Hello there! Nice to meet you! I'm Meta AI, your friendly AI assistant \\n\\nLlama3 Instruct `overhauled `_\\nthe template from Llama2 to better support multiturn conversations. The same text\\nin the Llama3 Instruct format would look like this:\\n\\n.. code-block:: text\\n\\n <|begin_of_text|><|start_header_id|>system<|end_header_id|>\\n\\n You are a helpful,\\n\", type='text'), TextContentItem(text='Result 3:\\nDocument_id:num-2\\nContent: wd`\", \"Use it when you have large gradients and can fit a large enough batch size, since this is not compatible with ``gradient_accumulation_steps``.\"\\n \":ref:`glossary_cpu_offload`\", \"Offloads optimizer states and (optionally) gradients to CPU, and performs optimizer steps on CPU. This can be used to significantly reduce GPU memory usage at the cost of CPU RAM and training speed. Prioritize using it only if the other techniques are not enough.\"\\n \":ref:`glossary_lora`\", \"When you want to significantly reduce the number of trainable parameters, saving gradient and optimizer memory during training, and significantly speeding up training. This may reduce training accuracy\"\\n \":ref:`glossary_qlora`\", \"When you are training a large model, since quantization will save 1.5 bytes * (# of model parameters), at the potential cost of some training speed and accuracy.\"\\n \":ref:`glossary_dora`\", \"a variant of LoRA that may improve model performance at the cost of slightly more memory.\"\\n\\n\\n.. note::\\n\\n In its current state, this tutorial is focused on single-device optimizations. Check in soon as we update this page\\n for the latest memory optimization features for distributed fine-tuning.\\n\\n.. _glossary_precision:\\n\\n\\nModel Precision\\n---------------\\n\\n*What\\'s going on here?*\\n\\nWe use the term \"precision\" to refer to the underlying data type used to represent the model and optimizer parameters.\\nWe support two data types in torchtune:\\n\\n.. note::\\n\\n We recommend diving into Sebastian Raschka\\'s `blogpost on mixed-precision techniques `_\\n for a deeper understanding of concepts around precision and data formats.\\n\\n* ``fp32``, commonly referred to as \"full-precision\", uses 4 bytes per model and optimizer parameter.\\n* ``bfloat16``, referred to as \"half-precision\", uses 2 bytes per model and optimizer parameter - effectively half\\n the memory of ``fp32``, and also improves training speed. Generally, if your hardware supports training with ``bfloat16``,\\n we recommend using it - this is the default setting for our recipes.\\n\\n.. note::\\n\\n Another common paradigm is \"mixed-precision\" training: where model weights are in ``bfloat16`` (or ``fp16``), and optimizer\\n states are in ``fp32``. Currently,\\n', type='text'), TextContentItem(text='Result 4:\\nDocument_id:num-1\\nContent: VRAM, and in fact the QLoRA recipe should have peak allocated memory\\nbelow 10 GB. You can also experiment with different configurations of LoRA and QLoRA, or even run a full fine-tune.\\nTry it out!\\n\\n|\\n\\nEvaluating fine-tuned Llama3-8B models with EleutherAI\\'s Eval Harness\\n---------------------------------------------------------------------\\n\\nNow that we\\'ve fine-tuned our model, what\\'s next? Let\\'s take our LoRA-finetuned model from the\\npreceding section and look at a couple different ways we can evaluate its performance on the tasks we care about.\\n\\nFirst, torchtune provides an integration with\\n`EleutherAI\\'s evaluation harness `_\\nfor model evaluation on common benchmark tasks.\\n\\n.. note::\\n Make sure you\\'ve first installed the evaluation harness via :code:`pip install \"lm_eval==0.4.*\"`.\\n\\nFor this tutorial we\\'ll use the `truthfulqa_mc2 `_ task from the harness.\\nThis task measures a model\\'s propensity to be truthful when answering questions and\\nmeasures the model\\'s zero-shot accuracy on a question followed by one or more true\\nresponses and one or more false responses. First, let\\'s copy the config so we can point the YAML\\nfile to our fine-tuned checkpoint files.\\n\\n.. code-block:: bash\\n\\n tune cp eleuther_evaluation ./custom_eval_config.yaml\\n\\nNext, we modify ``custom_eval_config.yaml`` to include the fine-tuned checkpoints.\\n\\n.. code-block:: yaml\\n\\n model:\\n _component_: torchtune.models.llama3.llama3_8b\\n\\n checkpointer:\\n _component_: torchtune.training.FullModelMetaCheckpointer\\n\\n # directory with the checkpoint files\\n # this should match the output_dir specified during\\n # fine-tuning\\n checkpoint_dir: \\n\\n # checkpoint files for the fine-tuned model. These will be logged\\n # at the end of your fine-tune\\n checkpoint_files: [\\n meta_model_0.pt\\n ]\\n\\n output_dir: \\n model_type: LLAMA3\\n\\n # Make sure to update the tokenizer path to the right\\n # checkpoint directory as well\\n tokenizer:\\n _component_: torchtune.models.llama3.llama3_tokenizer\\n path: /tokenizer.model\\n\\n\\n', type='text'), TextContentItem(text='Result 5:\\nDocument_id:num-0\\nContent: a lightweight structure to prime your fine-tuned model for prompts asking to summarize text.\\nThis would wrap around the user message, with the assistant message untouched.\\n\\n.. code-block:: python\\n\\n f\"Summarize this dialogue:\\\\n{dialogue}\\\\n---\\\\nSummary:\\\\n\"\\n\\nYou can fine-tune Llama2 with this template even though the model was originally pre-trained\\nwith the :class:`~torchtune.models.llama2.Llama2ChatTemplate`, as long as this is what the model\\nsees during inference. The model should be robust enough to adapt to a new template.\\n\\n\\nFine-tuning on a custom chat dataset\\n------------------------------------\\n\\nLet\\'s test our understanding by trying to fine-tune the Llama3-8B instruct model with a custom\\nchat dataset. We\\'ll walk through how to set up our data so that it can be tokenized\\ncorrectly and fed into our model.\\n\\nLet\\'s say we have a local dataset saved as a JSON file that contains conversations\\nwith an AI model. How can we get something like this into a format\\nLlama3 understands and tokenizes correctly?\\n\\n.. code-block:: python\\n\\n # data/my_data.json\\n [\\n {\\n \"dialogue\": [\\n {\\n \"from\": \"human\",\\n \"value\": \"What is your name?\"\\n },\\n {\\n \"from\": \"gpt\",\\n \"value\": \"I am an AI assistant, I don\\'t have a name.\"\\n },\\n {\\n \"from\": \"human\",\\n \"value\": \"Pretend you have a name.\"\\n },\\n {\\n \"from\": \"gpt\",\\n \"value\": \"My name is Mark Zuckerberg.\"\\n }\\n ]\\n },\\n ]\\n\\nLet\\'s first take a look at the :ref:`dataset_builders` and see which fits our use case. Since we\\nhave conversational data, :func:`~torchtune.datasets.chat_dataset` seems to be a good fit. For any\\ncustom local dataset we always need to specify ``source``, ``data_files``, and ``split`` for any dataset\\nbuilder in torchtune. For :func:`~torchtune.datasets.chat_dataset`, we additionally need to specify\\n``conversation_column`` and ``conversation_style``. Our data follows the ``\"sharegpt\"`` format, so\\nwe can specify that here. Altogether, our :func:`~torchtune.datasets.chat_dataset` call should\\nlook like so:\\n\\n.. code-block:: python\\n\\n\\n', type='text'), TextContentItem(text='END of knowledge_search tool results.\\n', type='text')]\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m*\u001b[0m\u001b[33m Fine\u001b[0m\u001b[33m-T\u001b[0m\u001b[33muning\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m3\u001b[0m\u001b[33m with\u001b[0m\u001b[33m Chat\u001b[0m\u001b[33m Data\u001b[0m\u001b[33m\n", + "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Model\u001b[0m\u001b[33m Precision\u001b[0m\u001b[33m\n", + "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Evalu\u001b[0m\u001b[33mating\u001b[0m\u001b[33m fine\u001b[0m\u001b[33m-t\u001b[0m\u001b[33muned\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m3\u001b[0m\u001b[33m-\u001b[0m\u001b[33m8\u001b[0m\u001b[33mB\u001b[0m\u001b[33m models\u001b[0m\u001b[33m with\u001b[0m\u001b[33m Ele\u001b[0m\u001b[33muther\u001b[0m\u001b[33mAI\u001b[0m\u001b[33m's\u001b[0m\u001b[33m Eval\u001b[0m\u001b[33m Harness\u001b[0m\u001b[33m\n", + "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Fine\u001b[0m\u001b[33m-t\u001b[0m\u001b[33muning\u001b[0m\u001b[33m on\u001b[0m\u001b[33m a\u001b[0m\u001b[33m custom\u001b[0m\u001b[33m chat\u001b[0m\u001b[33m dataset\u001b[0m\u001b[33m\n", + "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Token\u001b[0m\u001b[33mizing\u001b[0m\u001b[33m prompt\u001b[0m\u001b[33m templates\u001b[0m\u001b[33m &\u001b[0m\u001b[33m special\u001b[0m\u001b[33m tokens\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[30m\u001b[0m" ] } @@ -1861,216 +1394,6 @@ " log.print()" ] }, - { - "cell_type": "markdown", - "id": "yRzRwu8qxyl0", - "metadata": { - "id": "yRzRwu8qxyl0" - }, - "source": [ - "### 2.4. Code Execution Agent\n", - "\n", - "In this example, we will show how multiple tools can be called by the model - including web search and code execution. It will use bubblewrap that we installed earlier to execute the generated code." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "GvVRuhO-GOov", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "GvVRuhO-GOov", - "outputId": "39395e26-bb7d-4616-d51d-036c8bf41427" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[32mUser> Here is a csv, can you describe it?\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mimport\u001b[0m\u001b[36m pandas\u001b[0m\u001b[36m as\u001b[0m\u001b[36m pd\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Load\u001b[0m\u001b[36m data\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mdf\u001b[0m\u001b[36m =\u001b[0m\u001b[36m pd\u001b[0m\u001b[36m.read\u001b[0m\u001b[36m_csv\u001b[0m\u001b[36m('/\u001b[0m\u001b[36mvar\u001b[0m\u001b[36m/f\u001b[0m\u001b[36molders\u001b[0m\u001b[36m/m\u001b[0m\u001b[36mj\u001b[0m\u001b[36m/t\u001b[0m\u001b[36m_st\u001b[0m\u001b[36mv\u001b[0m\u001b[36m1\u001b[0m\u001b[36mys\u001b[0m\u001b[36m763\u001b[0m\u001b[36m7\u001b[0m\u001b[36mv\u001b[0m\u001b[36mq\u001b[0m\u001b[36mf\u001b[0m\u001b[36m2\u001b[0m\u001b[36m_b\u001b[0m\u001b[36m4\u001b[0m\u001b[36my\u001b[0m\u001b[36mf\u001b[0m\u001b[36m67\u001b[0m\u001b[36mm\u001b[0m\u001b[36m000\u001b[0m\u001b[36m0\u001b[0m\u001b[36mgn\u001b[0m\u001b[36m/T\u001b[0m\u001b[36m/tmp\u001b[0m\u001b[36mq\u001b[0m\u001b[36m2\u001b[0m\u001b[36mw\u001b[0m\u001b[36mjj\u001b[0m\u001b[36mmg\u001b[0m\u001b[36mf\u001b[0m\u001b[36m/s\u001b[0m\u001b[36mQ\u001b[0m\u001b[36mAm\u001b[0m\u001b[36muk\u001b[0m\u001b[36mV\u001b[0m\u001b[36mbin\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m.csv\u001b[0m\u001b[36m')\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Set\u001b[0m\u001b[36m options\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mpd\u001b[0m\u001b[36m.set\u001b[0m\u001b[36m_option\u001b[0m\u001b[36m('\u001b[0m\u001b[36mdisplay\u001b[0m\u001b[36m.max\u001b[0m\u001b[36m_columns\u001b[0m\u001b[36m',\u001b[0m\u001b[36m None\u001b[0m\u001b[36m)\n", - "\u001b[0m\u001b[36mpd\u001b[0m\u001b[36m.set\u001b[0m\u001b[36m_option\u001b[0m\u001b[36m('\u001b[0m\u001b[36mdisplay\u001b[0m\u001b[36m.max\u001b[0m\u001b[36m_rows\u001b[0m\u001b[36m',\u001b[0m\u001b[36m None\u001b[0m\u001b[36m)\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Describe\u001b[0m\u001b[36m the\u001b[0m\u001b[36m data\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mprint\u001b[0m\u001b[36m(df\u001b[0m\u001b[36m.describe\u001b[0m\u001b[36m())\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:code_interpreter Args:{'code': \"import pandas as pd\\n# Load data\\ndf = pd.read_csv('/var/folders/mj/t_stv1ys7637vqf2_b4yf67m0000gn/T/tmpq2wjjmgf/sQAmukVbinflation.csv')\\n# Set options\\npd.set_option('display.max_columns', None)\\npd.set_option('display.max_rows', None)\\n# Describe the data\\nprint(df.describe())\"}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:code_interpreter Response:error\n", - "[stdout]\n", - "[Errno 2] No such file or directory: 'bwrap'\n", - "[/stdout]\n", - "[stderr]\n", - "[Errno 2] No such file or directory: 'bwrap'\n", - "[/stderr]\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mIt\u001b[0m\u001b[33m seems\u001b[0m\u001b[33m that\u001b[0m\u001b[33m there\u001b[0m\u001b[33m was\u001b[0m\u001b[33m an\u001b[0m\u001b[33m issue\u001b[0m\u001b[33m with\u001b[0m\u001b[33m accessing\u001b[0m\u001b[33m the\u001b[0m\u001b[33m file\u001b[0m\u001b[33m.\u001b[0m\u001b[33m I\u001b[0m\u001b[33m'm\u001b[0m\u001b[33m a\u001b[0m\u001b[33m large\u001b[0m\u001b[33m language\u001b[0m\u001b[33m model\u001b[0m\u001b[33m,\u001b[0m\u001b[33m I\u001b[0m\u001b[33m don\u001b[0m\u001b[33m't\u001b[0m\u001b[33m have\u001b[0m\u001b[33m the\u001b[0m\u001b[33m ability\u001b[0m\u001b[33m to\u001b[0m\u001b[33m access\u001b[0m\u001b[33m or\u001b[0m\u001b[33m read\u001b[0m\u001b[33m files\u001b[0m\u001b[33m from\u001b[0m\u001b[33m your\u001b[0m\u001b[33m local\u001b[0m\u001b[33m system\u001b[0m\u001b[33m.\u001b[0m\u001b[33m However\u001b[0m\u001b[33m,\u001b[0m\u001b[33m I\u001b[0m\u001b[33m can\u001b[0m\u001b[33m guide\u001b[0m\u001b[33m you\u001b[0m\u001b[33m on\u001b[0m\u001b[33m how\u001b[0m\u001b[33m to\u001b[0m\u001b[33m describe\u001b[0m\u001b[33m a\u001b[0m\u001b[33m CSV\u001b[0m\u001b[33m file\u001b[0m\u001b[33m using\u001b[0m\u001b[33m Python\u001b[0m\u001b[33m's\u001b[0m\u001b[33m pandas\u001b[0m\u001b[33m library\u001b[0m\u001b[33m.\n", - "\n", - "\u001b[0m\u001b[33mTo\u001b[0m\u001b[33m describe\u001b[0m\u001b[33m a\u001b[0m\u001b[33m CSV\u001b[0m\u001b[33m file\u001b[0m\u001b[33m,\u001b[0m\u001b[33m you\u001b[0m\u001b[33m can\u001b[0m\u001b[33m use\u001b[0m\u001b[33m the\u001b[0m\u001b[33m `\u001b[0m\u001b[33mp\u001b[0m\u001b[33mandas\u001b[0m\u001b[33m`\u001b[0m\u001b[33m library\u001b[0m\u001b[33m in\u001b[0m\u001b[33m Python\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Here\u001b[0m\u001b[33m's\u001b[0m\u001b[33m a\u001b[0m\u001b[33m step\u001b[0m\u001b[33m-by\u001b[0m\u001b[33m-step\u001b[0m\u001b[33m guide\u001b[0m\u001b[33m:\n", - "\n", - "\u001b[0m\u001b[33m1\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Install\u001b[0m\u001b[33m the\u001b[0m\u001b[33m `\u001b[0m\u001b[33mp\u001b[0m\u001b[33mandas\u001b[0m\u001b[33m`\u001b[0m\u001b[33m library\u001b[0m\u001b[33m if\u001b[0m\u001b[33m you\u001b[0m\u001b[33m haven\u001b[0m\u001b[33m't\u001b[0m\u001b[33m already\u001b[0m\u001b[33m:\u001b[0m\u001b[33m `\u001b[0m\u001b[33mpip\u001b[0m\u001b[33m install\u001b[0m\u001b[33m pandas\u001b[0m\u001b[33m`\n", - "\u001b[0m\u001b[33m2\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Import\u001b[0m\u001b[33m the\u001b[0m\u001b[33m `\u001b[0m\u001b[33mp\u001b[0m\u001b[33mandas\u001b[0m\u001b[33m`\u001b[0m\u001b[33m library\u001b[0m\u001b[33m:\u001b[0m\u001b[33m `\u001b[0m\u001b[33mimport\u001b[0m\u001b[33m pandas\u001b[0m\u001b[33m as\u001b[0m\u001b[33m pd\u001b[0m\u001b[33m`\n", - "\u001b[0m\u001b[33m3\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Load\u001b[0m\u001b[33m the\u001b[0m\u001b[33m CSV\u001b[0m\u001b[33m file\u001b[0m\u001b[33m into\u001b[0m\u001b[33m a\u001b[0m\u001b[33m DataFrame\u001b[0m\u001b[33m:\u001b[0m\u001b[33m `\u001b[0m\u001b[33mdf\u001b[0m\u001b[33m =\u001b[0m\u001b[33m pd\u001b[0m\u001b[33m.read\u001b[0m\u001b[33m_csv\u001b[0m\u001b[33m('\u001b[0m\u001b[33myour\u001b[0m\u001b[33m_file\u001b[0m\u001b[33m.csv\u001b[0m\u001b[33m')\u001b[0m\u001b[33m`\n", - "\u001b[0m\u001b[33m4\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Use\u001b[0m\u001b[33m the\u001b[0m\u001b[33m `\u001b[0m\u001b[33mdescribe\u001b[0m\u001b[33m()`\u001b[0m\u001b[33m method\u001b[0m\u001b[33m to\u001b[0m\u001b[33m get\u001b[0m\u001b[33m a\u001b[0m\u001b[33m summary\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m data\u001b[0m\u001b[33m:\u001b[0m\u001b[33m `\u001b[0m\u001b[33mprint\u001b[0m\u001b[33m(df\u001b[0m\u001b[33m.describe\u001b[0m\u001b[33m())\u001b[0m\u001b[33m`\n", - "\n", - "\u001b[0m\u001b[33mThis\u001b[0m\u001b[33m will\u001b[0m\u001b[33m give\u001b[0m\u001b[33m you\u001b[0m\u001b[33m a\u001b[0m\u001b[33m summary\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m data\u001b[0m\u001b[33m,\u001b[0m\u001b[33m including\u001b[0m\u001b[33m the\u001b[0m\u001b[33m count\u001b[0m\u001b[33m,\u001b[0m\u001b[33m mean\u001b[0m\u001b[33m,\u001b[0m\u001b[33m standard\u001b[0m\u001b[33m deviation\u001b[0m\u001b[33m,\u001b[0m\u001b[33m minimum\u001b[0m\u001b[33m,\u001b[0m\u001b[33m \u001b[0m\u001b[33m25\u001b[0m\u001b[33mth\u001b[0m\u001b[33m percentile\u001b[0m\u001b[33m,\u001b[0m\u001b[33m \u001b[0m\u001b[33m50\u001b[0m\u001b[33mth\u001b[0m\u001b[33m percentile\u001b[0m\u001b[33m,\u001b[0m\u001b[33m \u001b[0m\u001b[33m75\u001b[0m\u001b[33mth\u001b[0m\u001b[33m percentile\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m maximum\u001b[0m\u001b[33m for\u001b[0m\u001b[33m each\u001b[0m\u001b[33m column\u001b[0m\u001b[33m.\n", - "\n", - "\u001b[0m\u001b[33mIf\u001b[0m\u001b[33m you\u001b[0m\u001b[33m provide\u001b[0m\u001b[33m the\u001b[0m\u001b[33m contents\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m CSV\u001b[0m\u001b[33m file\u001b[0m\u001b[33m,\u001b[0m\u001b[33m I\u001b[0m\u001b[33m can\u001b[0m\u001b[33m help\u001b[0m\u001b[33m you\u001b[0m\u001b[33m describe\u001b[0m\u001b[33m it\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[32mUser> Plot average yearly inflation as a time series\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mimport\u001b[0m\u001b[36m pandas\u001b[0m\u001b[36m as\u001b[0m\u001b[36m pd\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mimport\u001b[0m\u001b[36m matplotlib\u001b[0m\u001b[36m.pyplot\u001b[0m\u001b[36m as\u001b[0m\u001b[36m plt\u001b[0m\u001b[36m\n", - "\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Load\u001b[0m\u001b[36m the\u001b[0m\u001b[36m data\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mdf\u001b[0m\u001b[36m =\u001b[0m\u001b[36m pd\u001b[0m\u001b[36m.read\u001b[0m\u001b[36m_csv\u001b[0m\u001b[36m('/\u001b[0m\u001b[36mvar\u001b[0m\u001b[36m/f\u001b[0m\u001b[36molders\u001b[0m\u001b[36m/m\u001b[0m\u001b[36mj\u001b[0m\u001b[36m/t\u001b[0m\u001b[36m_st\u001b[0m\u001b[36mv\u001b[0m\u001b[36m1\u001b[0m\u001b[36mys\u001b[0m\u001b[36m763\u001b[0m\u001b[36m7\u001b[0m\u001b[36mv\u001b[0m\u001b[36mq\u001b[0m\u001b[36mf\u001b[0m\u001b[36m2\u001b[0m\u001b[36m_b\u001b[0m\u001b[36m4\u001b[0m\u001b[36my\u001b[0m\u001b[36mf\u001b[0m\u001b[36m67\u001b[0m\u001b[36mm\u001b[0m\u001b[36m000\u001b[0m\u001b[36m0\u001b[0m\u001b[36mgn\u001b[0m\u001b[36m/T\u001b[0m\u001b[36m/tmp\u001b[0m\u001b[36mq\u001b[0m\u001b[36m2\u001b[0m\u001b[36mw\u001b[0m\u001b[36mjj\u001b[0m\u001b[36mmg\u001b[0m\u001b[36mf\u001b[0m\u001b[36m/s\u001b[0m\u001b[36mQ\u001b[0m\u001b[36mAm\u001b[0m\u001b[36muk\u001b[0m\u001b[36mV\u001b[0m\u001b[36mbin\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m.csv\u001b[0m\u001b[36m')\n", - "\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Convert\u001b[0m\u001b[36m the\u001b[0m\u001b[36m '\u001b[0m\u001b[36myear\u001b[0m\u001b[36m'\u001b[0m\u001b[36m column\u001b[0m\u001b[36m to\u001b[0m\u001b[36m datetime\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mdf\u001b[0m\u001b[36m['\u001b[0m\u001b[36myear\u001b[0m\u001b[36m']\u001b[0m\u001b[36m =\u001b[0m\u001b[36m pd\u001b[0m\u001b[36m.to\u001b[0m\u001b[36m_datetime\u001b[0m\u001b[36m(df\u001b[0m\u001b[36m['\u001b[0m\u001b[36myear\u001b[0m\u001b[36m'])\n", - "\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Group\u001b[0m\u001b[36m by\u001b[0m\u001b[36m year\u001b[0m\u001b[36m and\u001b[0m\u001b[36m calculate\u001b[0m\u001b[36m the\u001b[0m\u001b[36m average\u001b[0m\u001b[36m inflation\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36maverage\u001b[0m\u001b[36m_in\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m =\u001b[0m\u001b[36m df\u001b[0m\u001b[36m.groupby\u001b[0m\u001b[36m('\u001b[0m\u001b[36myear\u001b[0m\u001b[36m')['\u001b[0m\u001b[36min\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m'].\u001b[0m\u001b[36mmean\u001b[0m\u001b[36m()\n", - "\n", - "\u001b[0m\u001b[36m#\u001b[0m\u001b[36m Plot\u001b[0m\u001b[36m the\u001b[0m\u001b[36m average\u001b[0m\u001b[36m yearly\u001b[0m\u001b[36m inflation\u001b[0m\u001b[36m as\u001b[0m\u001b[36m a\u001b[0m\u001b[36m time\u001b[0m\u001b[36m series\u001b[0m\u001b[36m\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.figure\u001b[0m\u001b[36m(figsize\u001b[0m\u001b[36m=(\u001b[0m\u001b[36m10\u001b[0m\u001b[36m,\u001b[0m\u001b[36m6\u001b[0m\u001b[36m))\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.plot\u001b[0m\u001b[36m(\u001b[0m\u001b[36maverage\u001b[0m\u001b[36m_in\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m.index\u001b[0m\u001b[36m,\u001b[0m\u001b[36m average\u001b[0m\u001b[36m_in\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m.values\u001b[0m\u001b[36m,\u001b[0m\u001b[36m marker\u001b[0m\u001b[36m='\u001b[0m\u001b[36mo\u001b[0m\u001b[36m')\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.title\u001b[0m\u001b[36m('\u001b[0m\u001b[36mAverage\u001b[0m\u001b[36m Year\u001b[0m\u001b[36mly\u001b[0m\u001b[36m In\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m')\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.xlabel\u001b[0m\u001b[36m('\u001b[0m\u001b[36mYear\u001b[0m\u001b[36m')\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.ylabel\u001b[0m\u001b[36m('\u001b[0m\u001b[36mAverage\u001b[0m\u001b[36m In\u001b[0m\u001b[36mflation\u001b[0m\u001b[36m')\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.grid\u001b[0m\u001b[36m(True\u001b[0m\u001b[36m)\n", - "\u001b[0m\u001b[36mplt\u001b[0m\u001b[36m.show\u001b[0m\u001b[36m()\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:code_interpreter Args:{'code': \"import pandas as pd\\nimport matplotlib.pyplot as plt\\n\\n# Load the data\\ndf = pd.read_csv('/var/folders/mj/t_stv1ys7637vqf2_b4yf67m0000gn/T/tmpq2wjjmgf/sQAmukVbinflation.csv')\\n\\n# Convert the 'year' column to datetime\\ndf['year'] = pd.to_datetime(df['year'])\\n\\n# Group by year and calculate the average inflation\\naverage_inflation = df.groupby('year')['inflation'].mean()\\n\\n# Plot the average yearly inflation as a time series\\nplt.figure(figsize=(10,6))\\nplt.plot(average_inflation.index, average_inflation.values, marker='o')\\nplt.title('Average Yearly Inflation')\\nplt.xlabel('Year')\\nplt.ylabel('Average Inflation')\\nplt.grid(True)\\nplt.show()\"}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:code_interpreter Response:error\n", - "[stdout]\n", - "[Errno 2] No such file or directory: 'bwrap'\n", - "[/stdout]\n", - "[stderr]\n", - "[Errno 2] No such file or directory: 'bwrap'\n", - "[/stderr]\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mIt\u001b[0m\u001b[33m seems\u001b[0m\u001b[33m that\u001b[0m\u001b[33m there\u001b[0m\u001b[33m was\u001b[0m\u001b[33m an\u001b[0m\u001b[33m issue\u001b[0m\u001b[33m with\u001b[0m\u001b[33m accessing\u001b[0m\u001b[33m the\u001b[0m\u001b[33m file\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Since\u001b[0m\u001b[33m I\u001b[0m\u001b[33m don\u001b[0m\u001b[33m't\u001b[0m\u001b[33m have\u001b[0m\u001b[33m the\u001b[0m\u001b[33m ability\u001b[0m\u001b[33m to\u001b[0m\u001b[33m access\u001b[0m\u001b[33m or\u001b[0m\u001b[33m read\u001b[0m\u001b[33m files\u001b[0m\u001b[33m from\u001b[0m\u001b[33m your\u001b[0m\u001b[33m local\u001b[0m\u001b[33m system\u001b[0m\u001b[33m,\u001b[0m\u001b[33m I\u001b[0m\u001b[33m'll\u001b[0m\u001b[33m provide\u001b[0m\u001b[33m a\u001b[0m\u001b[33m general\u001b[0m\u001b[33m solution\u001b[0m\u001b[33m.\n", - "\n", - "\u001b[0m\u001b[33mTo\u001b[0m\u001b[33m plot\u001b[0m\u001b[33m the\u001b[0m\u001b[33m average\u001b[0m\u001b[33m yearly\u001b[0m\u001b[33m inflation\u001b[0m\u001b[33m as\u001b[0m\u001b[33m a\u001b[0m\u001b[33m time\u001b[0m\u001b[33m series\u001b[0m\u001b[33m,\u001b[0m\u001b[33m you\u001b[0m\u001b[33m'll\u001b[0m\u001b[33m need\u001b[0m\u001b[33m to\u001b[0m\u001b[33m have\u001b[0m\u001b[33m the\u001b[0m\u001b[33m following\u001b[0m\u001b[33m data\u001b[0m\u001b[33m:\n", - "\n", - "\u001b[0m\u001b[33m-\u001b[0m\u001b[33m A\u001b[0m\u001b[33m column\u001b[0m\u001b[33m with\u001b[0m\u001b[33m the\u001b[0m\u001b[33m year\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m-\u001b[0m\u001b[33m A\u001b[0m\u001b[33m column\u001b[0m\u001b[33m with\u001b[0m\u001b[33m the\u001b[0m\u001b[33m inflation\u001b[0m\u001b[33m rate\u001b[0m\u001b[33m for\u001b[0m\u001b[33m each\u001b[0m\u001b[33m year\u001b[0m\u001b[33m\n", - "\n", - "\u001b[0m\u001b[33mHere\u001b[0m\u001b[33m's\u001b[0m\u001b[33m a\u001b[0m\u001b[33m general\u001b[0m\u001b[33m solution\u001b[0m\u001b[33m:\n", - "\n", - "\u001b[0m\u001b[33m1\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Load\u001b[0m\u001b[33m the\u001b[0m\u001b[33m data\u001b[0m\u001b[33m into\u001b[0m\u001b[33m a\u001b[0m\u001b[33m pandas\u001b[0m\u001b[33m DataFrame\u001b[0m\u001b[33m.\n", - "\u001b[0m\u001b[33m2\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Convert\u001b[0m\u001b[33m the\u001b[0m\u001b[33m '\u001b[0m\u001b[33myear\u001b[0m\u001b[33m'\u001b[0m\u001b[33m column\u001b[0m\u001b[33m to\u001b[0m\u001b[33m datetime\u001b[0m\u001b[33m.\n", - "\u001b[0m\u001b[33m3\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Group\u001b[0m\u001b[33m by\u001b[0m\u001b[33m year\u001b[0m\u001b[33m and\u001b[0m\u001b[33m calculate\u001b[0m\u001b[33m the\u001b[0m\u001b[33m average\u001b[0m\u001b[33m inflation\u001b[0m\u001b[33m.\n", - "\u001b[0m\u001b[33m4\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Plot\u001b[0m\u001b[33m the\u001b[0m\u001b[33m average\u001b[0m\u001b[33m yearly\u001b[0m\u001b[33m inflation\u001b[0m\u001b[33m as\u001b[0m\u001b[33m a\u001b[0m\u001b[33m time\u001b[0m\u001b[33m series\u001b[0m\u001b[33m using\u001b[0m\u001b[33m matplotlib\u001b[0m\u001b[33m.\n", - "\n", - "\u001b[0m\u001b[33mIf\u001b[0m\u001b[33m you\u001b[0m\u001b[33m provide\u001b[0m\u001b[33m the\u001b[0m\u001b[33m contents\u001b[0m\u001b[33m of\u001b[0m\u001b[33m the\u001b[0m\u001b[33m CSV\u001b[0m\u001b[33m file\u001b[0m\u001b[33m,\u001b[0m\u001b[33m I\u001b[0m\u001b[33m can\u001b[0m\u001b[33m help\u001b[0m\u001b[33m you\u001b[0m\u001b[33m plot\u001b[0m\u001b[33m the\u001b[0m\u001b[33m average\u001b[0m\u001b[33m yearly\u001b[0m\u001b[33m inflation\u001b[0m\u001b[33m as\u001b[0m\u001b[33m a\u001b[0m\u001b[33m time\u001b[0m\u001b[33m series\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m" - ] - } - ], - "source": [ - "from llama_stack_client import Document\n", - "\n", - "codex_agent = Agent(\n", - " client, \n", - " model=\"meta-llama/Llama-3.1-8B-Instruct\",\n", - " instructions=\"You are a helpful assistant\",\n", - " tools=[\n", - " \"builtin::code_interpreter\",\n", - " \"builtin::websearch\"\n", - " ],\n", - " sampling_params = {\n", - " \"max_tokens\" : 4096,\n", - " \"temperature\": 0.0\n", - " },\n", - ")\n", - "session_id = codex_agent.create_session(\"test-session\")\n", - "\n", - "\n", - "inflation_doc = Document(\n", - " content=\"https://raw.githubusercontent.com/meta-llama/llama-stack-apps/main/examples/resources/inflation.csv\",\n", - " mime_type=\"text/csv\",\n", - ")\n", - "\n", - "user_input = [\n", - " {\"prompt\": \"Here is a csv, can you describe it?\", \"documents\": [inflation_doc]},\n", - " {\"prompt\": \"Plot average yearly inflation as a time series\"},\n", - "]\n", - "\n", - "for input in user_input:\n", - " cprint(f'User> {input[\"prompt\"]}', 'green')\n", - " response = codex_agent.create_turn(\n", - "\n", - " messages=[\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": input[\"prompt\"],\n", - " }\n", - " ],\n", - " session_id=session_id,\n", - " documents=input.get(\"documents\", None)\n", - " )\n", - " # for chunk in response:\n", - " # print(chunk)\n", - "\n", - " for log in AgentEventLogger().log(response):\n", - " log.print()\n" - ] - }, - { - "cell_type": "markdown", - "id": "9GHJHfLmIQQi", - "metadata": { - "id": "9GHJHfLmIQQi" - }, - "source": [ - "- Now, use the generated response from agent to view the plot" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "JqBBVLKdIHHq", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 564 - }, - "id": "JqBBVLKdIHHq", - "outputId": "3c89c303-e7c0-4ae2-c271-f34a4d296a85" - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAIjCAYAAADFthA8AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAdE5JREFUeJzt3Xd4VGX6xvF7Jpn0QhLSgBBCJwmg9CYIUqQKFlyxYF3XtZfd/bmrArquZa3r2laxgxVUQAGRJr3XQKgJoQRCEtJISJvz+yMkEgEhMMmZyXw/15VLc+ZkzjPkJcyd9z3PazEMwxAAAAAAuAmr2QUAAAAAQF0iBAEAAABwK4QgAAAAAG6FEAQAAADArRCCAAAAALgVQhAAAAAAt0IIAgAAAOBWCEEAAAAA3AohCAAAAIBbIQQBANzS5Zdfrssvv9zsMqp8+umnatu2rWw2mxo0aCCpdmqcOHGiLBaLQ58TAFwNIQgAHOytt96SxWJR9+7dzS7FaaxYsUJWq1WPP/74GR9/4YUXZLFY9MMPP9RxZY5jsVh03333XdDXJicn69Zbb1WLFi303nvv6X//+99F1VJYWKiJEydq0aJFF/U8AFBfEYIAwMGmTJmiZs2aafXq1dq9e7fZ5TiFnj176u6779bLL7+spKSkao/t27dPTz/9tK677joNHz7cpArNtWjRItntdr3++uu69dZbNXbs2It6vsLCQk2aNOmMIeiJJ55QUVHRRT0/ALg6QhAAOFBKSoqWL1+uV155ReHh4ZoyZUqd12C323XixIk6v+65PP/882rYsKHuvvtuGYZRdfz++++XzWbT66+/Xid1FBYW1sl1aiIjI0OSqpbB1SZPT0/5+PjU+nUAwJkRggDAgaZMmaKQkBANHz5c1157bbUQVFpaqtDQUN12222nfV1eXp58fHz02GOPVR0rLi7WhAkT1LJlS3l7eysmJkZ//etfVVxcXO1rK5dhTZkyRQkJCfL29tacOXMkSS+99JJ69eqlsLAw+fr6qnPnzvrmm29Ou35RUZEeeOABNWzYUIGBgRo1apQOHjwoi8WiiRMnVjv34MGDuv322xUZGSlvb28lJCTogw8+OOefTXBwsF5//XUtW7ZM77//viTp22+/1cyZM/X8888rOjpadrtdr732mhISEuTj46PIyEjdfffdOnbsWLXn+v777zV8+HA1atRI3t7eatGihZ555hmVl5dXO+/yyy9XYmKi1q1bp759+8rPz09///vfT6utoKBA/v7+evDBB0977MCBA/Lw8NBzzz13ztd4qkWLFsliseirr77Ss88+qyZNmsjHx0dXXHFFtRnCZs2aacKECZKk8PDwM/6ZVyopKdFTTz2lzp07Kzg4WP7+/rrsssu0cOHCqnNSU1MVHh4uSZo0aZIsFku15zzTPUFlZWV65pln1KJFC3l7e6tZs2b6+9//ftpYa9asmUaMGKGlS5eqW7du8vHxUfPmzfXJJ5/U6M8GAExnAAAcpm3btsYdd9xhGIZh/PLLL4YkY/Xq1VWP33777UaDBg2M4uLial/38ccfG5KMNWvWGIZhGOXl5cbgwYMNPz8/46GHHjLeffdd47777jM8PT2Nq666qtrXSjLatWtnhIeHG5MmTTLefPNNY8OGDYZhGEaTJk2MP//5z8Z///tf45VXXjG6detmSDJmzZpV7TnGjh1rSDJuvvlm48033zTGjh1rdOzY0ZBkTJgwoeq8w4cPG02aNDFiYmKMp59+2nj77beNUaNGGZKMV1999bz+jIYPH26EhIQYe/bsMWJiYoxevXoZdrvdMAzDuPPOOw1PT0/jrrvuMt555x3jb3/7m+Hv72907drVKCkpqXqO0aNHG2PHjjX+/e9/G2+//bZx3XXXGZKMxx57rNq1+vXrZ0RFRRnh4eHG/fffb7z77rvGd999V/VYv379qs698cYbjcjISKOsrKzac7z44ouGxWIx9u3b97uvS5Jx7733Vn2+cOFCQ5Jx6aWXGp07dzZeffVVY+LEiYafn5/RrVu3qvO+/fZbY8yYMYYk4+233zY+/fRTY9OmTWes8ejRo0Z0dLTxyCOPGG+//bbx4osvGm3atDFsNlvV97ygoMB4++23DUnGmDFjjE8//bTac06YMMH47T//48ePNyQZ1157rfHmm28at9xyiyHJGD16dLXzYmNjjTZt2hiRkZHG3//+d+O///2v0alTJ8NisRhbt2793T8fAHAmhCAAcJC1a9cakox58+YZhmEYdrvdaNKkifHggw9WnTN37lxDkjFz5sxqXzts2DCjefPmVZ9/+umnhtVqNZYsWVLtvHfeeceQZCxbtqzqmCTDarUaSUlJp9VUWFhY7fOSkhIjMTHRGDBgQNWxdevWGZKMhx56qNq5t95662kh6I477jCio6ONzMzMauf+4Q9/MIKDg0+73pmkpqYa/v7+RmhoqGGz2YwtW7YYhmEYS5YsMSQZU6ZMqXb+nDlzTjt+puvcfffdhp+fn3HixImqY/369TMkGe+8885p5/82YFR+b2bPnl3tvA4dOlQ772zOFoLatWtXLfS+/vrrhqSq120YvwaTo0eP/m6NZWVlpwXoY8eOGZGRkcbtt99edezo0aOnfe9+e61KGzduNCQZd955Z7XzHnvsMUOSsWDBgqpjsbGxhiTjl19+qTqWkZFheHt7G48++ujZ/mgAwOmwHA4AHGTKlCmKjIxU//79JVUsU7v++uv1xRdfVC3TGjBggBo2bKgvv/yy6uuOHTumefPm6frrr6869vXXX6tdu3Zq27atMjMzqz4GDBggSdWWP0lSv379FB8ff1pNvr6+1a6Tm5uryy67TOvXr686Xrl07s9//nO1r73//vurfW4YhqZNm6aRI0fKMIxqdQ0ZMkS5ubnVnvdsYmNjNWHCBGVnZ+uRRx5RYmJi1WsODg7WoEGDqj13586dFRAQUO01n/q68vPzlZmZqcsuu0yFhYVKTk6udj1vb+8zLkH8rYEDB6pRo0bVljBu3bpVmzdv1k033XTOrz+b2267TV5eXlWfX3bZZZKkvXv31vi5PDw8qp7LbrcrOztbZWVl6tKly3n92Z/Jjz/+KEl65JFHqh1/9NFHJem0jn3x8fFVr0GqWMLXpk2bC3o9AGAWT7MLAID6oLy8XF988YX69++vlJSUquPdu3fXyy+/rPnz52vw4MHy9PTUNddco6lTp6q4uFje3t6aPn26SktLq4WgXbt2afv27VX3dvxW5Y30leLi4s543qxZs/TPf/5TGzdurHZ/x6n3hOzbt09Wq/W052jZsmW1z48ePaqcnBz973//O2sL59/WdTZdu3aVJHXp0qXq2K5du5Sbm6uIiIhzPndSUpKeeOIJLViwQHl5edXOy83NrfZ548aNq4WQs7Farbrxxhv19ttvq7CwUH5+fpoyZYp8fHx03XXXndfrOpOmTZtW+zwkJESSTrvP6Xx9/PHHevnll5WcnKzS0tKq42cbA+dS+f3/7fc7KipKDRo00L59+6od/+3rkSpe04W+HgAwAyEIABxgwYIFSk9P1xdffKEvvvjitMenTJmiwYMHS5L+8Ic/6N1339Xs2bM1evRoffXVV2rbtq06duxYdb7dblf79u31yiuvnPF6MTEx1T4/dWak0pIlSzRq1Cj17dtXb731lqKjo2Wz2fThhx9q6tSpNX6NdrtdknTTTTdp/PjxZzynQ4cONX7eU58/IiLirB31KgNhTk6O+vXrp6CgID399NNq0aKFfHx8tH79ev3tb3+rqrPSmf5szuaWW27Rv//9b3333Xe64YYbNHXqVI0YMULBwcEX/Lo8PDzOeNw4pUPe+frss8906623avTo0frLX/6iiIiIqqYNe/bsueAaJZ33BqqOfD0AYBZCEAA4wJQpUxQREaE333zztMemT5+ub7/9Vu+88458fX3Vt29fRUdH68svv1SfPn20YMEC/eMf/6j2NS1atNCmTZt0xRVXnPeb09+aNm2afHx8NHfuXHl7e1cd//DDD6udFxsbK7vdrpSUFLVq1arq+G/3OAoPD1dgYKDKy8s1cODAC6rp97Ro0UI///yzevfu/bvBZdGiRcrKytL06dPVt2/fquOnzsBdqMTERF166aWaMmWKmjRporS0NL3xxhsX/byO8s0336h58+aaPn16tXFR2V2uUk3GTOX3f9euXWrXrl3V8SNHjignJ0exsbEXXzgAOBnuCQKAi1RUVKTp06drxIgRuvbaa0/7uO+++5Sfn68ZM2ZIqlh2de2112rmzJn69NNPVVZWVm0pnCSNHTtWBw8e1HvvvXfG6x0/fvycdXl4eMhisVRrG52amqrvvvuu2nlDhgyRJL311lvVjv/2zb+Hh4euueYaTZs2TVu3bj3tekePHj1nTb9n7NixKi8v1zPPPHPaY2VlZcrJyamqQ6o+81BSUnJa/Rfq5ptv1k8//aTXXntNYWFhGjp0qEOe1xHO9NpXrVqlFStWVDvPz89Pkqr+zH7PsGHDJEmvvfZateOVs5DuuoEtgPqNmSAAuEgzZsxQfn6+Ro0adcbHe/ToUbVxamXYuf766/XGG29owoQJat++fbXfwEsVb8S/+uor/elPf9LChQvVu3dvlZeXKzk5WV999ZXmzp1b7X6aMxk+fLheeeUVXXnllRo3bpwyMjL05ptvqmXLltq8eXPVeZ07d9Y111yj1157TVlZWerRo4cWL16snTt3Sqo+q/D8889r4cKF6t69u+666y7Fx8crOztb69ev188//6zs7OwL+jOUKpo73H333Xruuee0ceNGDR48WDabTbt27dLXX3+t119/Xddee6169eqlkJAQjR8/Xg888IAsFos+/fRThy3HGjdunP7617/q22+/1T333CObzeaQ53WEESNGaPr06RozZoyGDx+ulJQUvfPOO4qPj1dBQUHVeb6+voqPj9eXX36p1q1bKzQ0VImJiVVNKE7VsWNHjR8/Xv/73/+qlhquXr1aH3/8sUaPHl3V6AMA6hNCEABcpMqb5wcNGnTGx61Wq4YPH64pU6YoKytLYWFh6tWrl2JiYrR///7TZoEqv+a7777Tq6++qk8++UTffvut/Pz81Lx5cz344INq3br1OesaMGCAJk+erOeff14PPfSQ4uLi9MILLyg1NbVaCJKkTz75RFFRUfr888/17bffauDAgfryyy/Vpk0b+fj4VJ0XGRmp1atX6+mnn9b06dP11ltvKSwsTAkJCXrhhRdq+Cd3unfeeUedO3fWu+++q7///e/y9PRUs2bNdNNNN6l3796SpLCwMM2aNUuPPvqonnjiCYWEhOimm27SFVdcUTWrdTEiIyM1ePBg/fjjj7r55psv+vkc6dZbb9Xhw4f17rvvau7cuYqPj9dnn32mr7/+WosWLap27vvvv6/7779fDz/8sEpKSjRhwoQzhqDKc5s3b66PPvpI3377raKiovT444+ftswOAOoLi8GdjACAM9i4caMuvfRSffbZZ7rxxhvNLqdOjRkzRlu2bDntvigAQP3APUEAABUVFZ127LXXXpPVaq3WfMAdpKen64cffnC6WSAAgOOwHA4AoBdffFHr1q1T//795enpqdmzZ2v27Nn64x//eFo77voqJSVFy5Yt0/vvvy+bzaa7777b7JIAALWEEAQAUK9evTRv3jw988wzKigoUNOmTTVx4sTTWnfXZ4sXL9Ztt92mpk2b6uOPP1ZUVJTZJQEAagn3BAEAAABwK9wTBAAAAMCtEIIAAAAAuBWXvifIbrfr0KFDCgwMrLaZHwAAAAD3YhiG8vPz1ahRI1mtvz/X49Ih6NChQ27TtQgAAADAue3fv19NmjT53XNcOgQFBgZKqnihQUFBptZSWlqqn376SYMHD5bNZjO1FrgHxhzqGmMOdYnxhrrGmHN9eXl5iomJqcoIv8elQ1DlErigoCCnCEF+fn4KCgriLw7qBGMOdY0xh7rEeENdY8zVH+dzmwyNEQAAAAC4FUIQAAAAALdCCAIAAADgVghBAAAAANwKIQgAAACAWyEEAQAAAHArhCAAAAAAboUQBAAAAMCtEIIAAAAAuBVCEAAAAAC3QggCAAAA4FYIQQAAAADcCiEIAAAAgFshBAEAAABwK4QgAAAAAG6FEAQAAADArRCCAAAA4NYMw9CGtByVlJtdCeoKIQgAAABubebmdI19b7U+2GmVYRhml4M6QAgCAACAW/tuw0FJ0vYcq+YkHTG5GtQFQhAAAADcVv6JUi3dlVn1+b9m79Dx4jITK0JdIAQBAADAbS1IzlBJuV2xoX4K8zZ0OK9Y/1mwy+yyUMsIQQAAAHBbc7YeliQNS4zU1XF2SdLkJSnanZFvZlmoZYQgAAAAuKWiknIt2nFUkjQ4PlKJIYauaBuuMruhJ79LoklCPUYIAgAAgFtavPOoikrL1biBrxIaBUqS/jGsjbw9rVqxN0szN6ebXCFqCyEIAAAAbmluUsVSuCsTo2SxWCRJMSF+urd/S0nSP2dtU/6JUtPqQ+0hBAEAAMDtlJTZ9fP2inbYQxOjqj32x77N1SzMTxn5xXr9Z5ok1EeEIAAAALid5XsylX+iTOGB3urUNKTaYz42D00clSBJ+nB5qnYcpklCfUMIAgAAgNupXAo3JCFSVqvltMcvbxOhKxOiVG439OT3W2mSUM+YHoIOHjyom266SWFhYfL19VX79u21du1as8sCAABAPVVuN/RTUsVSuCsTos963pMj4+Vr89DqlGx9t/FgXZWHOmBqCDp27Jh69+4tm82m2bNna9u2bXr55ZcVEhJy7i8GAAAALsCa1GxlHS9RAz+bujcPPet5jRv46v4rKpokPPtDsnKLaJJQX3iaefEXXnhBMTEx+vDDD6uOxcXFmVgRAAAA6rvKDVIHtouUzeP35wTu7NNc36w7oL1Hj+vVeTur7hWCazM1BM2YMUNDhgzRddddp8WLF6tx48b685//rLvuuuuM5xcXF6u4uLjq87y8PElSaWmpSkvNTeaV1ze7DrgPxhzqGmMOdYnxhtpitxuavbVi/59B7cJPG2u/HXMWSU8Nb6tbP1qnT1ak6upLotUuOrBOa8b5qcnPC4th4l1ePj4+kqRHHnlE1113ndasWaMHH3xQ77zzjsaPH3/a+RMnTtSkSZNOOz516lT5+fnVer0AAABwban50qtbPeVtNfRs13LZzvPmkI92WrUhy6q4QEMPJJTrDL0UYLLCwkKNGzdOubm5CgoK+t1zTQ1BXl5e6tKli5YvX1517IEHHtCaNWu0YsWK084/00xQTEyMMjMzz/lCa1tpaanmzZunQYMGyWazmVoL3ANjDnWNMYe6xHhDbXlx7k69tzRVwxOj9Nr1HaqOn2vMpeee0JX/WabCknI9PyZB13RqXJdl4zzk5eWpYcOG5xWCTF0OFx0drfj4+GrH2rVrp2nTpp3xfG9vb3l7e5923GazOc0PSGeqBe6BMYe6xphDXWK8wZEMw9BP2zMkScM6NDrj2DrbmGva0KaHBrbSv35M1r9/2qWh7Rsr2I+x6Uxq8rPC1O5wvXv31o4dO6od27lzp2JjY02qCAAAAPVV8uF87csqlLenVZe3Ca/x19/WO06tIgKUdbxEL/2049xfAKdlagh6+OGHtXLlSv3rX//S7t27NXXqVP3vf//Tvffea2ZZAAAAqIdmn+wK17d1uPy9a74gyuZh1dNXJUqSPlu1T1sO5Dq0PtQdU0NQ165d9e233+rzzz9XYmKinnnmGb322mu68cYbzSwLAAAA9dDckyHoyoSoC36Oni3CdNUljWQY0hPfb5Xdbtrt9bgIpt4TJEkjRozQiBEjzC4DAAAA9djeowXacSRfnlaLBraLvKjn+sewdpq/PUOb9ufoq7X79YduTR1UJeqKqTNBAAAAQF2Yk1QxC9SzRdhFNzSICPLRw4NaS5JemJOsY8dLLro+1C1CEAAAAOq9yqVwQxOjHfJ843vGqm1UoI4VlurFuTRJcDWEIAAAANRrB3OKtOlAriwWaVD8xS2Fq+R5SpOEL9akaeP+HIc8L+oGIQgAAAD1WuUsUNdmoQoPPH3PyQvVLS5UV3dqLMOQnvxuq8ppkuAyCEEAAACo1+Y4oCvc2Tw+tJ0CfTy15WCupq5Oc/jzo3YQggAAAFBvHc0v1pp92ZKkKxMdH4LCA7312OA2kqR/z0lWVkGxw68BxyMEAQAAoN76adthGYbUsUmwGjXwrZVr3Ni9qeKjg5R3okwvzEmulWvAsQhBAAAAqLcql8INqYVZoEqeHlY9M7qiScJXaw9o3cmZJzgvQhAAAADqpdzCUq3YkyWpdu4HOlXn2BCN7dJEkvTkd0kqK7fX6vVwcQhBAAAAqJd+3n5EZXZDbSID1Tw8oNav97cr2yrY16Zt6Xn6bOW+Wr8eLhwhCAAAAPXSnKSTXeFqcSncqcICvPWXIRVNEl7+aaeO5tMkwVkRggAAAFDvHC8u0y87j0qquxAkSTd0a6oOTYKVX1ym52Zvr7PromYIQQAAAKh3Fu04quIyu5qF+altVGCdXdfDatEzVyXKYpGmrz+o1Sk0SXBGhCAAAADUO7O3pkuq6ApnsVjq9NodYxroD12bSpKe/G6rSmmS4HQIQQAAAKhXTpSWa2FyhiRpaGK0KTX8dUgbhfjZtONIvj5enmpKDTg7QhAAAADqlaW7MnW8pFzRwT7q0DjYlBpC/L30tyvbSpJe+3mXjuSdMKUOnBkhCAAAAPVKZVe4IQlRslrrdincqcZ2idElMQ1UUFymZ3+gSYIzIQQBAACg3igtt2vetiOS6rYr3JlYrRb9c3RFk4QZmw5p+Z5MU+vBrwhBAAAAqDdW7c1WblGpwvy91LVZqNnlKLFxsG7qHitJeur7JJokOAlCEAAAAOqNyq5wgxMi5WHiUrhTPTa4jcL8vbQ7o0AfLE0xuxyIEAQAAIB6otxuaG5SxVK4IQnmLoU7VbCfTf83tKJJwuvzdyk9t8jkikAIAgAAQL2wPu2YMguKFejjqV4tGppdTjXXdGqiLrEhKiwp1z9n0STBbIQgAAAA1AtztlZ0hRvYLlJens71NtdqtejpqxJltUg/bEnXkl1HzS7JrTnX6AAAAAAugGEYVSHI7K5wZxPfKEi39GwmSZrwfZKKy8rNLciNEYIAAADg8rYezNPBnCL52jzUt1W42eWc1SODW6thgLf2Zh7X+0tokmAWQhAAAABc3pykiq5w/duGy9fLw+Rqzi7Ix6Z/DK9okvDGgl06mEOTBDMQggAAAODSDMPQ7JNL4ZypK9zZjL6ksbrFhepEqV1Pz0wyuxy3RAgCAACAS9udUaC9R4/Ly8OqAW0jzC7nnCwWi565KlEeVovmJh3Rwh0ZZpfkdghBAAAAcGmVs0B9WjVUoI/N5GrOT5uoQN3Wq5kkaeKMJJ0opUlCXSIEAQAAwKU5e1e4s3loUGtFBnlrX1ah/vfLXrPLcSuEIAAAAListKxCbUvPk4fVooHtIs0up0YCvD31j+HxkqQ3F+7W/uxCkytyH4QgAAAAuKzKrnDd40IV6u9lcjU1N7JDtHq1CFNxmV2TaJJQZwhBAAAAcFmV9wMNdbGlcJUsFouevipBNg+Lft6eoZ+3HTG7JLdACAIAAIBLOpx7QhvSciRJg12gNfbZtIwI1B19mkuSJs2iSUJdIAQBAADAJc1NqpgF6hwbosggH5OruTj3D2ip6GAf7c8u0luL9phdTr1HCAIAAIBLquoK58KzQJX8vT315IiKJgnvLN6j1MzjJldUvxGCAAAA4HKyj5doVUqWJNdrjX02QxOjdFmrhiops2vizCQZhmF2SfUWIQgAAAAuZ962w7IbUkKjIMWE+pldjkNYLBZNGpUgLw+rFu04qp9oklBrCEEAAABwOXNcvCvc2TQPD9Af+1Y0SXh65jYVlpSZXFH9RAgCAACAS8k7UaqluzMl1Z+lcKe6t39LNW7gq4M5RXpz4W6zy6mXCEEAAABwKQuTM1RabqhlRIBaRgSaXY7D+Xp5aMLIiiYJ//tlr/YcLTC5ovqHEAQAAACXMntL/ekKdzaD4iPVv024SssNTZxBkwRHIwQBAADAZRSVlGvRzgxJ9XMpXCWLxaKJoxLk5WnVkl2Z+vFk8INjEIIAAADgMhbvzNCJUruahPgqoVGQ2eXUqtgwf93Tr4Uk6ZlZ23S8mCYJjkIIAgAAgMs4dYNUi8VicjW1757LWygm1FeH807oPwt2mV1OvUEIAgAAgEsoLivX/O0VS+GGtq+/S+FO5WPz0KRRCZKkyUtStOtIvskV1Q+EIAAAALiE5XuylF9cpohAb10aE2J2OXVmQNtIDWwXqTK7oae+p0mCIxCCAAAA4BLmnlwKNyQhSlZr/V8Kd6oJI+Pl7WnVir1ZmrHpkNnluDxCEAAAAJxeWbldP207Iql+d4U7m5hQP93Xv6Uk6dkftiv/RKnJFbk2QhAAAACc3prUY8o+XqIGfjZ1jws1uxxT3NW3uZqF+Skjv1iv/UyThItBCAIAAIDTm7M1XZI0qF2kPD3c8y2sj81DE082SfhoeaqSD+eZXJHrcs8RBAAAAJdhtxuam1SxFM5dusKdzeVtInRlQpTK7Yae+o4mCReKEAQAAACntvFAjg7nnVCAt6d6t2xodjmme3JkvHxtHlqdmq1vNxw0uxyXRAgCAACAU6vsCjegbYS8PT1MrsZ8jRv46v4rKpok/OvH7cotoklCTRGCAAAA4LQMw9DskyHIHbvCnc2dfZqrebi/MgtK9Oq8nWaX43IIQQAAAHBa29PzlZZdKG9Pqy5vE252OU7Dy9Oqp0clSpI+WZGqpEO5JlfkWghBAAAAcFqVXeH6tQ6Xn5enydU4lz6tGmp4h2jZDemp75Nkt9Mk4XwRggAAAOC05iSxFO73PDk8Xn5eHlq375i+WX/A7HJcBiEIAAAATmnP0QLtPFIgT6tFV7SLNLscpxQV7KOHBraSJD0/O1m5hTRJOB+EIAAAADilOScbIvRq2VDBvjaTq3Fet/WOU6uIAGUfL9G/f0o2uxyXQAgCAACAU5p7cincUJbC/S6bh1VPX1XRJGHKqjRtOUCThHMhBAEAAMDpHDhWqM0HcmW1SIPiWQp3Lj1bhOmqSxrJMKQnvt9Kk4RzIAQBAADA6cxNOiJJ6tosVA0DvE2uxjX8Y1g7BXh7atP+HH25dr/Z5Tg1QhAAAACcTmVrbLrCnb+IIB89PKi1JOmFOck6drzE5IqcFyEIAAAATiUj/4TW7jsmSRqSQAiqifE9Y9U2KlA5haV6cS5NEs6GEAQAAACn8lPSERmG1DGmgRo18DW7HJfieUqThC/W7NeGtGMmV+ScCEEAAABwKnSFuzjd4kJ1dafGMgzpye+3qpwmCachBAEAAMBp5BSWaMWeLEnSlSyFu2CPD22nQB9PbT2Yp6mr08wux+kQggAAAOA0ft6eoTK7obZRgWrW0N/sclxWeKC3HhvcRpL07znJyiwoNrki50IIAgAAgNOgK5zj3NQjVgmNgpR3okwvzKZJwqkIQQAAAHAKBcVl+mVXpiRCkCN4WC1VTRK+XndA6/Zlm1yR8yAEAQAAwCks2pGhkjK74hr6q01koNnl1AudY0N0fZcYSdIT3yWprNxuckXOgRAEAAAApzB7a0VXuCEJUbJYLCZXU3/89co2Cva1aXt6nj5buc/scpwCIQgAAACmO1FaroXJGZJoje1oYQHe+suQiiYJL/+0Uxn5J0yuyHyEIAAAAJhuya5MFZaUq1Gwjzo0CTa7nHrnhm5N1aFJsPKLy/T8jzRJIAQBAADAdHMql8IlshSuNnhYLXrmqkRZLNL0DQe1am+W2SWZihAEAAAAU5WW2/Xz9iOS2CC1NnWMaaAbujWVJD31fZJK3bhJAiEIAAAAplq5N0u5RaVqGOClLs1CzS6nXvvL4DYK8bNpx5F8fbw81exyTEMIAgAAgKkqu8INio+Sh5WlcLUpxN9L/ze0rSTptZ936UieezZJIAQBAADANOV2Qz8lVSyFoytc3biuc4wuiWmgguIyPfvDdrPLMQUhCAAAAKZZt++YMguKFeTjqR7Nw8wuxy1YrRb9c3SirBZpxqZDWr470+yS6hwhCAAAAKap7Ao3sF2kvDx5a1pXEhsH66YesZKkp2YkqaTMvZokMNIAAABgCsMwNDepIgRdyVK4OvfooDYK8/fS7owCfbgsxexy6pSpIWjixImyWCzVPtq2bWtmSQAAAKgjWw7m6mBOkfy8PNS3dbjZ5bidYD+bHh/WTpL0+vxdSs8tMrmiumP6TFBCQoLS09OrPpYuXWp2SQAAAKgDlUvh+reJkI/Nw+Rq3NPVlzZWl9gQFZaU65+z3KdJgukhyNPTU1FRUVUfDRs2NLskAAAA1DLDMKpC0BCWwpnGarXo6asqmiT8sCVdv+w8anZJdcLT7AJ27dqlRo0aycfHRz179tRzzz2npk2bnvHc4uJiFRcXV32el5cnSSotLVVpaWmd1Hs2ldc3uw64D8Yc6hpjDnWJ8Vb/7TpSoL2Zx2XzsOiyFiGmf6/decy1CvfVzT2a6uMVaZrw/VbNvK+XvF2wSUVNvncWwzCMWqzld82ePVsFBQVq06aN0tPTNWnSJB08eFBbt25VYGDgaedPnDhRkyZNOu341KlT5efnVxclAwAAwAHm7Ldo9gEPJYTY9ce27tWZzBkVlUn/2uihvFKLhseUa3AT0yLCBSssLNS4ceOUm5uroKCg3z3X1BD0Wzk5OYqNjdUrr7yiO+6447THzzQTFBMTo8zMzHO+0NpWWlqqefPmadCgQbLZbKbWAvfAmENdY8yhLjHe6r+Rb65Q8uF8PT8mQdd0amx2OYw5Sd9vStdj32yRj82qOQ/0VuMGvmaXVCN5eXlq2LDheYUg05fDnapBgwZq3bq1du/efcbHvb295e3tfdpxm83mNIPVmWqBe2DMoa4x5lCXGG/1076s40o+nC8Pq0VDEhs51ffYncfcNZ1j9PW6g1qVkq3n5uzUuzd3MbukGqnJ982pFvsVFBRoz549io6ONrsUAAAA1JLKhgg9m4cpxN/L5GpQyWKx6JnRifKwWjQ36YgW7sgwu6RaY2oIeuyxx7R48WKlpqZq+fLlGjNmjDw8PHTDDTeYWRYAAABq0Wy6wjmt1pGBur13M0nSxBlJOlFabm5BtcTUEHTgwAHdcMMNatOmjcaOHauwsDCtXLlS4eFslgUAAFAfpecWaeP+HFks0pD4SLPLwRk8OLC1IoO8tS+rUO8u3mt2ObXC1HuCvvjiCzMvDwAAgDo29+QsUOemIYoI8jG5GpxJgLennhger/s/36C3Fu3WmEsbq2lY/erE7FT3BAEAAKB+m5NUEYKuZCmcUxvRIVq9WoSpuMyuSTOTzC7H4QhBAAAAqBNZBcVanZItSRqSQAhyZhaLRU9flSibh0XzkzP087YjZpfkUIQgAAAA1Il5247IbkiJjYMUE1q/llfVRy0jAnRHn+aSpIkz61eTBEIQAAAA6kTlUrihiWyH4iruH9BS0cE+OnCsSG8tPPNenq6IEAQAAIBal1tUqmW7MyWxFM6V+Ht76qkR8ZKkdxbvVWrmcZMrcgxCEAAAAGrdwuQMlZYbahURoJYRAWaXgxq4MjFKl7VqqJJyuybMSJJhGGaXdNEIQQAAAKh1s7emS6IrnCuqbJLg5WHV4p1HNTfJ9ZskEIIAAABQqwpLyrR451FJhCBXFdfQX3/sW9Ek4ZlZ21RYUmZyRReHEAQAAIBatXjHUZ0otSsm1Ffx0UFml4MLdG//lmrcwFcHc4r03wWu3SSBEAQAAIBadWpXOIvFYnI1uFC+Xh6aMLKiScJ7S/Zqz9ECkyu6cIQgAAAA1JrisnIt2J4hia5w9cGg+Ej1bxOu0nJDE7533SYJhCAAAADUmuW7s5RfXKbIIG9dGtPA7HJwkSwWiyaOSpCXp1VLd2fqxy2HzS7pghCCAAAAUGsqu8INSYiS1cpSuPogNsxf9/RrIamiSUJBses1SSAEAQAAoFaUlds1b1tFO+UrWQpXr9xzeQs1DfXT4bwTemP+LrPLqTFCEAAAAGrF6tRsHSssVYifTd3iQs0uBw7kY/PQxFEVTRImL01RauZxkyuqGU+zCwAAAED9NGdrxf0ig+Ij5enB797rmwFtI3VDtxh1bRaq2DA/s8upEUIQAAAAHM5uNzT3lNbYqJ+eu7qD2SVcECI5AAAAHG7D/hwdyStWoLenerUMM7scoBpCEAAAAByuchZoQLsIeXt6mFwNUB0hCAAAAA5lGEZVa2y6wsEZEYIAAADgUNvS87Q/u0g+Nqv6tQk3uxzgNIQgAAAAOFRlV7h+rcPl50UfLjgfQhAAAAAcqjIE0RUOzooQBAAAAIfZnVGgXRkFsnlY1L9thNnlAGdECAIAAIDDVHaF692yoYJ9bSZXA5wZIQgAAAAOQ1c4uAJCEAAAABxif3ahth7Mk9UiDYqPNLsc4KwIQQAAAHCIyqVw3eJCFRbgbXI1wNkRggAAAOAQlV3hWAoHZ0cIAgAAwEXLyDuhdWnHJElDEglBcG6EIAAAAFy0uduOyDCkS2IaKDrY1+xygN9FCAIAAMBFm1u1QSqzQHB+hCAAAABclGPHS7Rib5Yk6UpCEFwAIQgAAAAX5eftR1RuN9QuOkixYf5mlwOcEyEIAAAAF4WucHA1hCAAAABcsILiMi3ZlSlJGtqeEATXQAgCAADABVuQnKGScruaN/RXq4gAs8sBzgshCAAAABessivckMQoWSwWk6sBzo/nhXxRTk6OVq9erYyMDNnt9mqP3XLLLQ4pDAAAAM7tRGm5Fu7IkERrbLiWGoegmTNn6sYbb1RBQYGCgoKqJX6LxUIIAgAAcBO/7DyqwpJyNW7gq/aNg80uBzhvNV4O9+ijj+r2229XQUGBcnJydOzYsaqP7Ozs2qgRAAAATmhO0smlcAkshYNrqXEIOnjwoB544AH5+fnVRj0AAABwASVldv287YgkNkiF66lxCBoyZIjWrl1bG7UAAADARazcm6W8E2VqGOCtzrEhZpcD1EiN7wkaPny4/vKXv2jbtm1q3769bDZbtcdHjRrlsOIAAADgnGaf7Ao3OCFSHlaWwsG11DgE3XXXXZKkp59++rTHLBaLysvLL74qAAAAOK1yu6F52ypCEF3h4IpqHIJ+2xIbAAAA7mVtarYyC0oU7GtTj+ZhZpcD1BibpQIAAKBGKrvCDWwXKZsHbyfhei5o1C5evFgjR45Uy5Yt1bJlS40aNUpLlixxdG0AAABwMoZhaO7J+4HoCgdXVeMQ9Nlnn2ngwIHy8/PTAw88oAceeEC+vr664oorNHXq1NqoEQAAAE5i84FcHco9IT8vD13WqqHZ5QAXpMb3BD377LN68cUX9fDDD1cde+CBB/TKK6/omWee0bhx4xxaIAAAAJxHZVe4/m0j5GPzMLka4MLUeCZo7969Gjly5GnHR40apZSUFIcUBQAAAOdjGIbmbE2XJF2ZwFI4uK4ah6CYmBjNnz//tOM///yzYmJiHFIUAAAAnM/OIwVKzSqUl6dV/dtGmF0OcMFqvBzu0Ucf1QMPPKCNGzeqV69ekqRly5bpo48+0uuvv+7wAgEAAOAcZp+cBerbqqECvGv8NhJwGjUevffcc4+ioqL08ssv66uvvpIktWvXTl9++aWuuuoqhxcIAAAA5zCnqitctMmVABfngiL8mDFjNGbMGEfXAgAAACeVmnlcyYfz5Wm1aGA7lsLBtbG7FQAAAM6pcoPUni3C1MDPy+RqgItzXjNBoaGh2rlzpxo2bKiQkBBZLJaznpudne2w4gAAAOAcKltjD6ErHOqB8wpBr776qgIDA6v+//dCEAAAAOqXQzlF2rQ/RxaLNDgh0uxygIt2XiFo/PjxVf9/66231lYtAAAAcEJzTy6F6xIboohAH5OrAS5eje8J8vDwUEZGxmnHs7Ky5OHBrsEAAAD1DV3hUN/UOAQZhnHG48XFxfLy4iY5AACA+iSzoFhrUivu+R7CUjjUE+fdIvs///mPJMlisej9999XQEBA1WPl5eX65Zdf1LZtW8dXCAAAANPM23ZEdkPq0CRYTUL8zC4HcIjzDkGvvvqqpIqZoHfeeafa0jcvLy81a9ZM77zzjuMrBAAAgGnoCof66LxDUEpKiiSpf//+mj59ukJCQmqtKAAAAJgvt6hUy3dnSpKuTCQEof447xBUaeHChbVRBwAAAJzMguQjKrMbah0ZoBbhAef+AsBF1DgESdKBAwc0Y8YMpaWlqaSkpNpjr7zyikMKAwAAgLlmbznZFY6lcKhnahyC5s+fr1GjRql58+ZKTk5WYmKiUlNTZRiGOnXqVBs1AgAAoI4VlpRp8c6jkmiNjfqnxi2yH3/8cT322GPasmWLfHx8NG3aNO3fv1/9+vXTddddVxs1AgAAoI4t2nFUxWV2NQ31U7voQLPLARyqxiFo+/btuuWWWyRJnp6eKioqUkBAgJ5++mm98MILDi8QAAAAda9yg9ShiVGyWCwmVwM4Vo1DkL+/f9V9QNHR0dqzZ0/VY5mZmY6rDAAAAKYoLivXguQMSdIQusKhHqrxPUE9evTQ0qVL1a5dOw0bNkyPPvqotmzZounTp6tHjx61USMAAADq0LLdmSooLlNUkI8uadLA7HIAh6txCHrllVdUUFAgSZo0aZIKCgr05ZdfqlWrVnSGAwAAqAcqu8INSYiU1cpSONQ/NQ5BzZs3r/p/f39/vfPOOw4tCAAAAOYpK7dr3vYjkugKh/qrxvcEAQAAoP5alZKtnMJShfp7qWuzELPLAWrFec0EhYSEnHdXkOzs7IsqCAAAAOap7Ao3OD5Snh78vhz103mFoNdee62WywAAAIDZ7HZDc5NO3g9EVzjUY+cVgjZt2qRnnnlG/v7++uWXX9SrVy95etb4diIAAAA4sQ37jykjv1iB3p7q1SLM7HKAWnNec5xvvPFGVUe4/v37s+QNAACgHqpcCndFuwh5e3qYXA1Qe85rOqdZs2b6z3/+o8GDB8swDK1YsUIhIWe+Ua5v374OLRAAAAC1zzAMzT4Zgq5kKRzqufMKQf/+97/1pz/9Sc8995wsFovGjBlzxvMsFovKy8sdWiAAAABqX9KhPB04ViQfm1X9WkeYXQ5Qq84rBI0ePVqjR49WQUGBgoKCtGPHDkVE8JcDAACgvqhcCnd56wj5erEUDvVbjbobBAQEaOHChYqLi6MxAgAAQD0y52RXuKHtWQqH+q/GSaZfv36y2+3auXOnMjIyZLfbqz3OPUEAAACuZXdGvnZnFMjmYVH/tqz2Qf1X4xC0cuVKjRs3Tvv27ZNhGNUe454gAAAA11O5FK5Py4YK8rGZXA1Q+2q8DfCf/vQndenSRVu3blV2draOHTtW9XExrbOff/55WSwWPfTQQxf8HAAAAKg5usLB3dR4JmjXrl365ptv1LJlS4cVsWbNGr377rvq0KGDw54TAAAA57Y/u1BJh/JktUiD4glBcA81ngnq3r27du/e7bACCgoKdOONN+q99947695DAAAAqB2VS+G6x4Up1N/L5GqAulHjmaD7779fjz76qA4fPqz27dvLZqu+brSmszn33nuvhg8froEDB+qf//zn755bXFys4uLiqs/z8vIkSaWlpSotLa3RdR2t8vpm1wH3wZhDXWPMoS4x3urO7K3pkqTB8eFu/efNmHN9NfneWYzfdjc4B6v19Mkji8UiwzBq3Bjhiy++0LPPPqs1a9bIx8dHl19+uS655BK99tprZzx/4sSJmjRp0mnHp06dKj8/v/O+LgAAAKTcEumpdRW/E5/UqUwNvE0uCLgIhYWFGjdunHJzcxUUFPS759Z4JiglJeWCCzvV/v379eCDD2revHny8fE5r695/PHH9cgjj1R9npeXp5iYGA0ePPicL7S2lZaWat68eRo0aNBps2NAbWDMoa4x5lCXGG91Y8qqNEnJuiQmWOPGdDe7HFMx5lxf5Sqx81HjEBQbG1vTLzmjdevWKSMjQ506dao6Vl5erl9++UX//e9/VVxcLA+P6rsVe3t7y9v79F9R2Gw2pxmszlQL3ANjDnWNMYe6xHirXfOSj0qShrWP5s/5JMac66rJ9+28Q9CMGTPO67xRo0ad13lXXHGFtmzZUu3YbbfdprZt2+pvf/vbaQEIAAAAjnPseIlW7q3Y3uTKhGiTqwHq1nmHoNGjR5/znJrcExQYGKjExMRqx/z9/RUWFnbacQAAADjWvO1HVG43FB8dpKZh3FsN93LeIchut9dmHQAAAKhDc9ggFW6sxvcE1aZFixaZXQIAAEC9l3+iVEt3ZUqShhKC4IZqvFkqAAAAXNuC5AyVlNvVPNxfLSMCzC4HqHOEIAAAADczN6liKdzQxChZLBaTqwHqHiEIAADAjRSVlGvhydbYdIWDuyIEAQAAuJFfdh1VUWm5GjfwVWJjczebB8xyQSEoJydH77//vh5//HFlZ1f0l1+/fr0OHjzo0OIAAADgWKd2hWMpHNxVjbvDbd68WQMHDlRwcLBSU1N11113KTQ0VNOnT1daWpo++eST2qgTAAAAF6mkzK6ftx+RRGtsuLcazwQ98sgjuvXWW7Vr1y75+PhUHR82bJh++eUXhxYHAAAAx1mxN0v5J8oUHuitzk1DzC4HME2NQ9CaNWt09913n3a8cePGOnz4sEOKAgAAgOPN2ZouSRocHymrlaVwcF81DkHe3t7Ky8s77fjOnTsVHh7ukKIAAADgWOV2Qz8lVSyFG5pIVzi4txqHoFGjRunpp59WaWmpJMlisSgtLU1/+9vfdM011zi8QAAAAFy8NanZyjpeomBfm7o3DzW7HMBUNQ5BL7/8sgoKChQREaGioiL169dPLVu2VGBgoJ599tnaqBEAAAAXqbIr3KD4SNk82CUF7q3G3eGCg4M1b948LV26VJs3b1ZBQYE6deqkgQMH1kZ9AAAAuEh2u6G5SSdbYyfQFQ6ocQiq1KdPH/Xp08eRtQAAAKAWbD6Yq/TcE/L38lCfVg3NLgcwXY1D0H/+858zHrdYLPLx8VHLli3Vt29feXh4XHRxAAAAuHizT3aF6982Qj423qMBNQ5Br776qo4eParCwkKFhFT0lz927Jj8/PwUEBCgjIwMNW/eXAsXLlRMTIzDCwYAAMD5MwxDc0/eD0RXOKBCje+K+9e//qWuXbtq165dysrKUlZWlnbu3Knu3bvr9ddfV1pamqKiovTwww/XRr0AAACogeTD+UrNKpS3p1WXt2E7E0C6gJmgJ554QtOmTVOLFi2qjrVs2VIvvfSSrrnmGu3du1cvvvgi7bIBAACcQGVXuL6tw+XvfcG3gwP1So1ngtLT01VWVnba8bKyMh0+XPGXrFGjRsrPz7/46gAAAHBRKkMQXeGAX9U4BPXv31933323NmzYUHVsw4YNuueeezRgwABJ0pYtWxQXF+e4KgEAAFBje48WaMeRfHlaLRrYLtLscgCnUeMQNHnyZIWGhqpz587y9vaWt7e3unTpotDQUE2ePFmSFBAQoJdfftnhxQIAAOD8zU06Iknq2SJMwX42k6sBnEeNF4ZGRUVp3rx5Sk5O1s6dOyVJbdq0UZs2barO6d+/v+MqBAAAwAWZc7I19pWJLIUDTnXBd8e1bdtWbdu2dWQtAAAAcJCDOUXadCBXFos0OJ4QBJzqgkLQgQMHNGPGDKWlpamkpKTaY6+88opDCgMAAMCFq9wbqGtsqMIDvU2uBnAuNQ5B8+fP16hRo9S8eXMlJycrMTFRqampMgxDnTp1qo0aAQAAUENzkk52hWMpHHCaGjdGePzxx/XYY49py5Yt8vHx0bRp07R//37169dP1113XW3UCAAAgBo4ml+sNanZkqQhhCDgNDUOQdu3b9ctt9wiSfL09FRRUZECAgL09NNP64UXXnB4gQAAAKiZeduOyDCkjk2C1biBr9nlAE6nxiHI39+/6j6g6Oho7dmzp+qxzMxMx1UGAACACzL7ZFc4ZoGAM6vxPUE9evTQ0qVL1a5dOw0bNkyPPvqotmzZounTp6tHjx61USMAAADOU25hqVbsyZIkXZlACALOpMYh6JVXXlFBQYEkadKkSSooKNCXX36pVq1a0RkOAADAZD9vP6Iyu6E2kYFqHh5gdjmAU6pRCCovL9eBAwfUoUMHSRVL4955551aKQwAAAA1R1c44NxqdE+Qh4eHBg8erGPHjtVWPQAAALhAx4vL9MvOo5IIQcDvqXFjhMTERO3du7c2agEAAMBFWLTjqIrL7IoN81PbqECzywGcVo1D0D//+U899thjmjVrltLT05WXl1ftAwAAAOaYuemQpIpZIIvFYnI1gPOqcWOEYcOGSZJGjRpV7S+XYRiyWCwqLy93XHUAAAA4L/uzC/XTtor7ga6+tInJ1QDOrcYhaOHChbVRBwAAAC7CR8tTZTeky1o1VBuWwgG/q8YhqF+/frVRBwAAAC5Q/olSfblmvyTp9j5xJlcDOL8a3xMkSUuWLNFNN92kXr166eDBg5KkTz/9VEuXLnVocQAAADi3r9YeUEFxmVpGBKhfq3CzywGcXo1D0LRp0zRkyBD5+vpq/fr1Ki4uliTl5ubqX//6l8MLBAAAwNmV2w19uCxFknR77zhZrTREAM7lgrrDvfPOO3rvvfdks9mqjvfu3Vvr1693aHEAAAD4fT8lHdaBY0UK8bPp6k6NzS4HcAk1DkE7duxQ3759TzseHBysnJwcR9QEAACA8zR5acUs0I3dY+Vj8zC5GsA11DgERUVFaffu3acdX7p0qZo3b+6QogAAAHBum/bnaO2+Y7J5WHRLz1izywFcRo1D0F133aUHH3xQq1atksVi0aFDhzRlyhQ99thjuueee2qjRgAAAJxB5SzQyI6NFBHkY3I1gOuocYvs//u//5PdbtcVV1yhwsJC9e3bV97e3nrsscd0//3310aNAAAA+I1DOUX6YUu6JOkO2mIDNVLjEGSxWPSPf/xDf/nLX7R7924VFBQoPj5eAQEBtVEfAAAAzuDjFakqtxvq0TxUCY2CzS4HcCk1Xg732WefqbCwUF5eXoqPj1e3bt0IQAAAAHXoeHGZPl+VJkm6ow/3ZAM1VeMQ9PDDDysiIkLjxo3Tjz/+qPLy8tqoCwAAAGcxbf0B5Z0oU7MwP13RNsLscgCXU+MQlJ6eri+++EIWi0Vjx45VdHS07r33Xi1fvrw26gMAAMAp7HZDH5xsiHB7HzZHBS5EjUOQp6enRowYoSlTpigjI0OvvvqqUlNT1b9/f7Vo0aI2agQAAMBJ85MzlJpVqCAfT13TqYnZ5QAuqcaNEU7l5+enIUOG6NixY9q3b5+2b9/uqLoAAABwBpOX7pUk3dC9qfy9L+qtHOC2ajwTJEmFhYWaMmWKhg0bpsaNG+u1117TmDFjlJSU5Oj6AAAAcNLWg7lauTdbnlaLbu3VzOxyAJdV418f/OEPf9CsWbPk5+ensWPH6sknn1TPnj1rozYAAACcovJeoGHtoxUd7GtyNYDrqnEI8vDw0FdffaUhQ4bIw8Oj2mNbt25VYmKiw4oDAABAhYy8E5q5+ZAkNkcFLlaNQ9CUKVOqfZ6fn6/PP/9c77//vtatW0fLbAAAgFrwyYp9Ki031CU2RB1jGphdDuDSLuieIEn65ZdfNH78eEVHR+ull17SgAEDtHLlSkfWBgAAAElFJeWasmqfJOnOy5gFAi5WjWaCDh8+rI8++kiTJ09WXl6exo4dq+LiYn333XeKj4+vrRoBAADc2vQNB3SssFQxob4aFB9ldjmAyzvvmaCRI0eqTZs22rx5s1577TUdOnRIb7zxRm3WBgAA4PZO3Rz11l5x8mBzVOCinfdM0OzZs/XAAw/onnvuUatWrWqzJgAAAJy0eNdR7Tl6XAHenhrbhc1RAUc475mgpUuXKj8/X507d1b37t313//+V5mZmbVZGwAAgNurnAX6Q9cYBfrYTK4GqB/OOwT16NFD7733ntLT03X33Xfriy++UKNGjWS32zVv3jzl5+fXZp0AAABuJ/lwnpbsypTVIo1nc1TAYWrcHc7f31+33367li5dqi1btujRRx/V888/r4iICI0aNao2agQAAHBLlbNAVyZGKSbUz+RqgPrjgltkS1KbNm304osv6sCBA/r8888dVRMAAIDbyywo1ncb2RwVqA0XFYIqeXh4aPTo0ZoxY4Yjng4AAMDtfbZyn0rK7LokpoE6NQ0xuxygXnFICAIAAIDjnCgt16crKjZHvaNPnCwW2mIDjkQIAgAAcDIzNh5S1vESNQr20dBENkcFHI0QBAAA4EQMw9AHyyoaIozv1UyeHrxdAxyNv1UAAABOZNnuLCUfzpefl4f+0K2p2eUA9RIhCAAAwIm8v3SvJGlslxgF+7I5KlAbCEEAAABOYndGvhbtOCqLRbqtdzOzywHqLUIQAACAk/hgWaokaWC7SMWG+ZtbDFCPEYIAAACcQPbxEk1ff0ASm6MCtY0QBAAA4ASmrtqnE6V2JTYOUve4ULPLAeo1QhAAAIDJSsrs+oTNUYE6QwgCAAAw2azNh5SRX6yIQG8Nb9/I7HKAeo8QBAAAYCLDMDR56a+bo3p58vYMqG38LQMAADDRyr3ZSjqUJx+bVePYHBWoE4QgAAAAE1XOAl3TqYlC/L1MrgZwD4QgAAAAk6RmHtf85COSpNtpiw3UGUIQAACAST5cliLDkPq3CVeL8ACzywHcBiEIAADABLmFpfpqbcXmqHde1tzkagD3QggCAAAwwedr0lRUWq62UYHq1SLM7HIAt0IIAgAAqGOl5XZ9vDxVUsW9QGyOCtQtQhAAAEAdm731sNJzT6hhgJdGdWRzVKCuEYIAAADqkGEYmrxkryTp5h7N5GPzMLkiwP2YGoLefvttdejQQUFBQQoKClLPnj01e/ZsM0sCAACoVev2HdOmA7ny8rTqxh5sjgqYwdQQ1KRJEz3//PNat26d1q5dqwEDBuiqq65SUlKSmWUBAADUmsrNUcdc0lgNA7xNrgZwT55mXnzkyJHVPn/22Wf19ttva+XKlUpISDCpKgAAgNqxP7tQc5MOS2JzVMBMpoagU5WXl+vrr7/W8ePH1bNnzzOeU1xcrOLi4qrP8/LyJEmlpaUqLS2tkzrPpvL6ZtcB98GYQ11jzKEu1dfxNnnJHtkNqU/LMDUP86l3r8+V1dcx505q8r2zGIZh1GIt57Rlyxb17NlTJ06cUEBAgKZOnaphw4ad8dyJEydq0qRJpx2fOnWq/Pz8artUAACAC3aiTHpqvYeKyy36U9tytQsx9S0YUO8UFhZq3Lhxys3NVVBQ0O+ea3oIKikpUVpamnJzc/XNN9/o/fff1+LFixUfH3/auWeaCYqJiVFmZuY5X2htKy0t1bx58zRo0CDZbDZTa4F7YMyhrjHmUJfq43j7cPk+/Wv2DrUI99fs+3uxN5CTqY9jzt3k5eWpYcOG5xWCTF8O5+XlpZYtW0qSOnfurDVr1uj111/Xu+++e9q53t7e8vY+/QZCm83mNIPVmWqBe2DMoa4x5lCX6st4Kyu365OVaZKkO/o0l5eXl8kV4Wzqy5hzRzX5vjndPkF2u73abA8AAICr+2nbER04VqQQP5uu7tTY7HIAt2fqTNDjjz+uoUOHqmnTpsrPz9fUqVO1aNEizZ0718yyAAAAHKqyLfZNPWLZHBVwAqaGoIyMDN1yyy1KT09XcHCwOnTooLlz52rQoEFmlgUAAOAwG/fnaN2+Y7J5WHRzj1izywEgk0PQ5MmTzbw8AABAraucBRrZsZEignxMrgaA5IT3BAEAANQXh3KK9OOWdEnSHWyOCjgNQhAAAEAt+Xh5qsrthno2D1NCo2CzywFwEiEIAACgFhwvLtPU1ZVtsZkFApwJIQgAAKAWfLPugPJPlCmuob8GtI0wuxwApyAEAQAAOFi53dCHyyoaItzWu5msVovJFQE4FSEIAADAweZvP6LUrEIF+9p0becmZpcD4DcIQQAAAA5W2Rb7hm5N5edl6o4kAM6AEAQAAOBAWw/malVKtjytFo3vxeaogDMiBAEAADjQBydngYa1j1Z0sK/J1QA4E0IQAACAgxzJO6EZmw5Jku68jLbYgLMiBAEAADjIJytSVWY31LVZiDo0aWB2OQDOghAEAADgAEUl5Zqyis1RAVdACAIAAHCA6RsOKKewVDGhvhoUH2V2OQB+ByEIAADgItntRlVb7Nt6xcmDzVEBp0YIAgAAuEiLdx7V3qPHFejtqbFdY8wuB8A5EIIAAAAuUuUs0PVdYxTgzeaogLMjBAEAAFyE5MN5Wro7U1aLNL5XM7PLAXAeCEEAAAAXYfKSilmgoYnRign1M7kaAOeDEAQAAHCBjuYX6/uNFZuj3k5bbMBlEIIAAAAu0Gcr96mk3K5LYhqoc2yI2eUAOE+EIAAAgAtworRcn63cJ4nNUQFXQwgCAAC4AN9vPKis4yVq3MBXQxPZHBVwJYQgAACAGjKMXzdHHd8rVp4evKUCXAl/YwEAAGpo6e5M7TxSID8vD13ftanZ5QCoIUIQAABADVXOAo3tEqNgX5vJ1QCoKUIQAABADezOyNeiHUdlsUi39W5mdjkALgAhCAAAoAYmL02VJA1qF6nYMH9ziwFwQQhBAAAA5yn7eImmrz8gibbYgCsjBAEAAJynqav2qbjMrsTGQeoWF2p2OQAuECEIAADgPBSXlevjFb9ujmqxWEyuCMCFIgQBAACch1mb0nU0v1iRQd4a3r6R2eUAuAiEIAAAgHM4dXPUW3o2k5cnb6EAV8bfYAAAgHNYuTdb29Lz5GOz6sbubI4KuDpCEAAAwDlMXrpXknRNpyZq4OdlcjUALhYhCAAA4HekZB7X/OQMSdLttMUG6gVCEAAAwO/4cFmKDEMa0DZCLcIDzC4HgAMQggAAAM4it7BUX69lc1SgviEEAQAAnMXU1WkqKi1X26hA9WoRZnY5AByEEAQAAHAGpeV2fbw8VRKbowL1DSEIAADgDH7ckq7DeSfUMMBboy5hc1SgPiEEAQAA/Mapm6Pe3CNW3p4eJlcEwJEIQQAAAL+xdt8xbT6QKy9Pq27sweaoQH1DCAIAAPiNyUsqZoGuvrSxGgZ4m1wNAEcjBAEAAJxif3ahftp2WBKbowL1FSEIAADgFB8uS5XdkC5r1VCtIwPNLgdALSAEAQAAnJR3olRfrkmTxOaoQH1GCAIAADjpqzX7dbykXK0iAtSvdbjZ5QCoJYQgAAAASWXldn24LFVSxb1AbI4K1F+EIAAAAEk/bTuigzlFCvX30phLG5tdDoBaRAgCAACQ9P6SvZKkG7s3lY+NzVGB+owQBAAA3N6GtGNan5YjLw+rbu4Za3Y5AGoZIQgAALi9yUsrNkcd2bGRIgJ9TK4GQG0jBAEAALd2MKdIs7dWbI5KW2zAPRCCAACAW/t4earK7YZ6Ng9TfKMgs8sBUAcIQQAAwG0dLy7T56vZHBVwN4QgAADgtr5eu1/5J8oU19BfA9pGmF0OgDpCCAIAAG6p3G7ow+WpkqTbezeT1crmqIC7IAQBAAC39PP2I9qXVahgX5uu6dzE7HIA1CFCEAAAcEuVbbFv6NZUfl6eJlcDoC4RggAAgNvZejBXq1Oy5Wm1aHwvNkcF3A0hCAAAuJ3KWaDhHaIVHexrcjUA6hohCAAAuJXDuSc0c9MhSbTFBtwVIQgAALiVT1akqsxuqGuzEHVo0sDscgCYgBAEAADcRlFJuaZWbY7a3ORqAJiFEAQAANzGtPUHlFNYqqahfhoUH2l2OQBMQggCAABuwW439MHJhgi39momDzZHBdwWIQgAALiFRTsztDfzuAK9PTW2a4zZ5QAwETuDAQDgAGXldmUXlujY8VJlHS/WseOlyj5erNyiUnVtFqruzcPMLtHtVbbF/kO3GAV48xYIcGf8BABcUNKhXE1duU8H9lvV8ki+EpqEml0SUK8YhqHCknJlHy857SPreImOVf638NfjuUWlv/ucIzpE64nh8YoK9qmjV4FTbU/P07LdWbJapPG9mpldDgCTEYIAF2G3G5qfnKHJS/dq5d7sk0etWvzfFerWLFQ39miqoYnR8vJklSvwW+V2QzmFvwk0hSXKLjg9zFR+FJfZa3wdi0Vq4GtTqL9X1YfVYtHcpMOatTldC5Mz9NDA1rq1dzPZPPi7WpcqZ4GGJkarSYifydUAMBshCHByx4vLNG39AX2wNEWpWYWSJA+rRVcmROrAwUPamuOh1anZWp2arWcCtmlslxiN696Uf+RRrxWVlFeFmOzCEmUfL1b2yeVnZ5q9ySkqlWHU/DpenlaFnRJoQv29FOLnVXEswEuhftUfa+Dndcab7bcezNVT32/V+rQcPfvjdn21dr+evipRPVuwRK4uZOSf0IyNFZuj3s7mqABECAKc1qGcIn28IlWfr0pT3okySVKgj6fGdW+q8T2bKdzfUz/+eECd+lyuaRvS9fnqNB3JK9Zbi/bo7cV7NKBNhG7qGat+rcJlpQMSnJjdbii3qPRkmDm/j6LS8gu6VvApszS/F2YqP/y8PGSxXPzfn8TGwfrmT730zfoDen52snZlFOiG91Zq9CWN9Pdh7RQRxBK52vTZyjSVlNt1adMG6hwbYnY5AJwAIQhwMhv352jy0hT9uCVd5faKX103C/PTbb3jdG3nJvI/eTNvaWnF/QdRQT56aGBr3du/peZvP6LPVqZp6e5MzU/O0PzkDMWE+mpct1iN7dJEYQHepr0uuI/isjPfS3Omj2OFJTpWWFo11mvC5mH5NcwEeCnU31uhfraK//pX/DfE36Ywf++TszQ2U5egWa0Wje0So8HxkXrppx2asipN3208pJ+3Z+jhQa01vmesPFki53AnSss1ZeU+SdIdzAIBOIkQBDiBcruhn5IOa/LSFK3dd6zqeI/mobqjT3MNaBtxzv0sbB5WXZkYrSsTo7X3aIGmrErT12v3a392kV6Yk6xX5+3UsPZRurlnrDo1DXHIb7fhPkrL7dp0IFdbsi06vu6gck+UV1+CVljx32PHS1VQXHZB1wj09qyYlfE/fWYmxN/rtGVpAd6eLjmOG/h56Z+j22tslxg9+X2SNu3P0TOztunrtfv1zOhEdW1GoxNH+m7DQWUdL1HjBr66MiHK7HIAOAlCEGCi/BOl+nLNfn20PFUHjhVJqvjt9siOjXR77zglNg6+oOdtHh6gJ0fE67HBbTRz8yFNWblPmw7k6ruNh/TdxkNqGxWom3vGavQljatmloDfKrcbWpWSpVmb0zV7S7qOFZZK8pB2JJ3zaz2sll+Xm50jzFTO5rhbU48OTRro23t66cu1+/XCnGQlH87Xde+s0NWdGuvxoe0UHsjM7cUyDEMfLKtoiDC+FzNtAH7Fux/ABPuzC/XhslR9tXZ/1W/NQ/xsurF7rG7pGeuw+wN8vTw0tkuMxnaJ0eYDOfps5T59v/GQkg/n6x/fbtVzPybr6k6NdVOPWLWODHTINeHa7HZD69OOadbmdP2wJV1H84urHmvga1OQtURxjcMVFuCtsGqh5tclaKF+Xgrydc1ZmrpmtVp0Q7emujIhSi/O3aEv1qRp+vqDmrftiB4b3EY3dm/KG/eLsGRXpnYeKZC/l4eu79rU7HIAOBFCEFBHDMPQun3HNHlpiuYmHVblLRAtIwJ0e+84jbm0sXy9PGrt+h2aNNCL1zbQP4bF65v1BzRl5T7tzTyuT1bs0ycr9qlbXKhu6hGrKxOi3O438u7OMAxtOZirmZsO6YfN6TqUe6LqsSAfTw1NjNaIjtHqEhOkn+bO0bBhnWSz2UysuP4J8ffSc1e31/VdY/Tkd1u15WCuJsxI0pdrKpbIcTP/halsi31dlxgF+zJmAfyKEATUstJyu37ckq4PlqZo04HcquOXtWqoO/rEqW8dd28L9rPpjj5xur13My3fk6VPV+zTvO1HtDolW6tTstUwwEvXd43RDd1os12fGYah5MP5mrX5kGZuSldadmHVYwHenhoUH6mRHaPVp2V4VSiubMaB2nNJTAN9d29vfb46Tf+eu0Pb0vN0zdvLNbZLE/3tyrY0N6mBXUfytXjnUVks0m29m5ldDgAnQwgCakluYammrk7TJytSlX7yN+tenlaNuaSxbu8TpzZR5i4/s1gs6t2yoXq3bKjDuSf0+eo0fbGmos32mwv36O1FezSgbYRu7EGb7fpkd0aBZm0+pFmb07U7o6DquI/NqivaRWpkh0a6vE24fGy1NyuJ3+dhteimHrEamhilF+Yk66u1B/TV2gOas/Ww/nJlW43r1vScjVKgqnuBBrWLVGyYv8nVAHA2hCDAwVIyj+vDZSn6eu2Bqr1MGgZ46eYezXRjj6Zq6IS/yY0K9tHDg1rrvgEt9fO2I/ps1T4t252ln7dn6OftGWoa6qdx3ZtqbJcYhfp7mV0uaigtq1AzTwaf7el5Vce9PKy6vE24RnRspCvaRtAkw8mEBXjrxWs76vquTfXkd1u1LT1PT363VV+dXCJ3SUwDs0t0WtnHSzR9/UFJtMUGcGb8iwc4gGEYWrE3Sx8sTdH85IyqnenbRgXq9j5xGtWxkUv8Zt3mYdXQ9tEa2j5ae44WaMrKNH2zbr/Ssgv1/OxkvTJvp4a3j9ZNPWLVqWkDbnx3Yum5Rfphc7pmbjpUbRmmp9WiPq0aamSHRhqUEKkgH+6TcHadY0M0477emrIqTS/9tENbDuZqzFvL9IeuMfrrkLYK4RcTp5mycp+Ky+xq3zhY3eJoOQ7gdIQg4CKUlNk1c9MhTV6aom2n/IZ9QNsI3dEnTr1ahLlsUGgRHqCnRsbrL0PaaOamQ/ps1T5tPpCrbzcc1LcbDqpddJBu7hGrqy5pxAyCk8jIP6HZWw5r1uZDWpP6635TVovUs0WYRnRopCsTonjT7II8Pawa36uZhrWP1vOzkzVt/QF9vnq/Zm89rL9d2VbXd4lhyepJxWXl+njFr5ujuurPYAC1i3cuwAXIPl6iKSv36ZOV+6paCPvYrLqmUxPd1jtOLSMCTK7QcXy9PDS2a4zGdo3Rpv0VbbZnbDqk7el5+vu3W/SvH7frmpNttlvRZrvOHTteotlbK4LPyr1ZVV0HJalbs1CN6BitoYnR7DlTT4QHeuvlsR11fdcYPfX9ViUfztfj07foizX79c+rEtW+yYXtLVafzNyUrsyCYkUGeWtY+2izywHgpAhBQA3szsjX5KWpmr7+gIrL7JKkyCBv3dKzmcZ1a1rvf8PeMaaBOsY00D+Gt9M36w5oyqo0pWQe18cr9unjk222b+4RqyG02a5VeSdK9VPSEc3cdEjLdmeq7JTk0zGmgUZ2iNbwDtGKDvY1sUrUpm5xoZp1fx99vGKfXp23U5v252jUm0t1Y/ememxwGzXwq98/i87GMIyqtti39GzGzyEAZ2VqCHruuec0ffp0JScny9fXV7169dILL7ygNm3amFkWUI1hGFqyK1OTl6Zo8c6jVccTGwfpzj7NNax9tNv9Q9vAz0t3XtZct/eO0/I9Wfps5W/bbHvrD11jdEP3pmrcgDfijnC8uEw/bz+iWZvTtXjHUZWU26sei48O0oiO0RrRvpGahtHW3F14elh1R584jewQrX/9uF3fbTykz1am6ccth/V/V7bVtZ2buN0SuRV7s7Q9PU++Ng/d2J3NUQGcnakhaPHixbr33nvVtWtXlZWV6e9//7sGDx6sbdu2yd+fdpYw14nScn234aA+WJainUcqWglbLBXtVu/oE6ducaFuv9bcevIm+z6tfm2z/fnqNGXkF+u/C3frrUW7NaBtpG7q0bTO90OqD06UlmvRjgzN3JSu+clHdKL01+DTMiJAIzs00oiO0WoRXn+WX6LmIoJ89NofLtX1XZvqqe+3aldGgf46bbO+WJOmZ0YnKqGR+yyRm7ykYhboms6N3XY2DMD5MTUEzZkzp9rnH330kSIiIrRu3Tr17dv3tPOLi4tVXFxc9XleXsWN6KWlpaZv4ld5fbPrwMXLLCjWlFX7NXXNfmUfr/h++nl56NpOjXVLz6aKDa34TXtZWZmZZTrdmAvz89B9l8fp7stiNT/5qKau3q8Ve7P18/Yj+nn7EcWE+OqGbk10zaWNabP9O0rK7Fq6J0s/bjmsn7dn6HhJedVjTUN9Nbx9lIYnRql1ZEBVCK+rMeBsYw7VdWkapO//3EOfrEzTGwv2aH1ajka+UbFE7qEBLRTk61qdAGs63lIyj2t+coYk6eZuMYxT1Bg/41xfTb53FsMwjHOfVjd2796tVq1aacuWLUpMTDzt8YkTJ2rSpEmnHZ86dar8/FgCgotz8Li0KN2qdZkWlRsVby5DvAz1jbarR4QhP+6gq7EjRdKyw1atPmpRUXnFn6mnxdClYYZ6R9nVLKBids3dlRvSrlyL1mdatDn71z8rqWIMXhpmqFNDu5r48+eF85NTLH23z6oNWRVLdQNshq6KtatrQ6PejqGv91q19IhV8Q3surud/dxfAKDeKSws1Lhx45Sbm6ugoKDfPddpQpDdbteoUaOUk5OjpUuXnvGcM80ExcTEKDMz85wvtLaVlpZq3rx5GjRokGw21/ptmzuz2w0t3pWpj5bv0/K92VXHL4kJ1m09YzU4PkKeHs55v48rjbnCkjL9sOWwpq4+oK2Hfm0l3i4qUOO6xWhkhyi3a7Ndbje0dt8x/bDlsOZuO1I16yhJ4QFeGpoYpeHto3RJk2CnWUboSmMOFZbvydKkWcnam3lcktQltoEmjminNlHO38mxJuMtp7BUfV9arKJSuz65rbN6Ng+roypRn/AzzvXl5eWpYcOG5xWCnOZdx7333qutW7eeNQBJkre3t7y9T2/zarPZnGawOlMtOLvCkjJNW39QHy5L0d6jFW8OrBZpaGK0bu8Tp86xISZXeP5cYcwF22wa1yNO43rEadP+HH26cp9mbjqk7Yfz9eSMbXpx7k5d7QZttg3D0Pq0HM3afEg/bE5XRv6vv9QJ9a8IPiM6NFK3uFB5OEnwORNXGHOo0K9tlOa0jNDkpSn6z/xdWrsvR1e9vVLjezbTw4NaKdAFNss9n/H29YZ9Kiq1q21UoC5rHen292vi4vAzznXV5PvmFCHovvvu06xZs/TLL7+oSZMmZpeDeuxw7gl9siJVU1alKbeo4jfvgd6e+kO3GI3v1UxNQlhWWdsq22w/cZY2293jQnVzz1gNjq8fbbYNw9DWg3matfmQZm1O18GcoqrHgnw8NSQhSiM7NlKvFmFOO+sI1+bladU9l7fQVZc00j9/2KYftxzWB8tSNHPzIT0xvJ1GdWzk0qGhtNyuT5azOSqAmjE1BBmGofvvv1/ffvutFi1apLi4ODPLQT225UCuJi/dq1mb06v2VIkJ9dXtveN0XZcYBbjZUixncGqb7WV7MivabG87olUp2Vp1ss32Dd1idEO3pmrkgm22dxzO18xNhzRr8yGlZhVWHff38tCg+EiN6NBIl7VuKG9PDxOrhDtp1MBXb93YWb/sPKoJM5KUknlcD36xUVNXVXSRa+2is7A/bknX4bwTahjgrVGXNDK7HAAuwtR3fvfee6+mTp2q77//XoGBgTp8+LAkKTg4WL6+rvemB86l3G5o3rYj+mBpilan/nq/T7dmobq9T5wGxUc69ZIjd2G1WnRZq3Bd1ipc6blF+nz1fn1xss32Gwt2682FFW22b+4Zq8taNnSa+2POZO/RAs3anK6Zmw5pV0ZB1XEfm1VXtI3UiA7R6t82Qj42gg/M07d1uOY8dJneX5KiNxbs0qqUbA17fYlu691MDw5s7VK/FKq+OWosv1QAcN5M/Un39ttvS5Iuv/zyasc//PBD3XrrrXVfEOqFguIyfbVmvz5anqq07IrfwHtaLRrRIVp39Gmu9k3cZ88MVxMd7KtHBrXW/QNaat62I/ps5T4t35NV1WY7NsxPN3Zvqus6xyjESdps788u1KzN6Zq1+ZCSTmn64OVhVd/W4RrZMVoD20W6XeMHODdvTw/d27+lRnVspGdmbdNP247ovSUpmrHpkJ4YHq8RHaJdYlnZmtRj2nwgV16eVjZHBVAjpi+HAxzlwLFCfbw8VV+s3q/84oo9fIJ9bRrXvanG92ymqGAfkyvE+bJ5WDWsfbSGtY/W7owCTVm1T9+sO6B9WYX614/JeumnnRrRIVo39YjVpTEN6vzN2uHcE1X3+Gzcn1N13MNqUZ+WDTWiQ7QGJ0Qp2MX2ZYH7iQn10/9u6aKFyRmaODNJ+7IKdf/nG/TFmjRNGpWolhHOvRHv5KV7JUlXX9pYYQGnN04CgLPhV5Nweev2HdMHS1M0J+mwyk/e79O8ob9u6xOnazo1lp8Xw9yVtYwI0ISRCfrLkDaauemQPl25T1sP5mn6+oOavv6gEhoF6aYesbrqkka1+r3OLCjW7C3pmrkpXWv2ZavydzgWi9SzeZhGdGikKxOj2AgWLql/2wj1bBGmdxfv1VuLdmvZ7iwNff0X3dGnuR64oqVT/hxNyyrUT9uOSJJu78M9xQBqxvl+qgHnoazcrjlJhzV5aYo2pOVUHe/VIkx39IlT/zYRTn3vCGrOz8tT13dtqrFdYrTpQK4+XbGvagna49O36F8/bNc1nZvoph5N1TLCMTd45xSWaM7Ww5q1OV3L92TKfsrkdZfYEI3s2EhD20cpIpBZRrg+H5uHHhzYSmMubaxJM5M0PzlD7yzeoxkbD+rJEfG6MjHKqZbIfbg8RYZRcY+TqzZ1AGAeQhBcSm5Rqb5ck6aPl++rajXs5WHVqEsa6fbecYpvZO6muah9FotFl8Q00CUxDfTkiIo225+t3KfUrEJ9tDxVHy1PVY/mobqpx4W12c4/Uap5245o5qZDWrIrs6qboCR1bBKsER0aaXiHaJfsWAecj6Zhfpp8a1f9vO2IJs5M0oFjRbpnynpd1qqhJo1KUPNw85fI5Z0o1Vdr9kuqaIsNADVFCIJL2Jd1XB8uS9XXa/freEm5pIrNJW/qEaubejTlN/Fu6rdttj9dsU8/bz+ilXuztXJvtsIDvfWHrudus11YUqb52zM0c9MhLdp5VCVl9qrH2kYFamTHRhrRIVqxYf518bIApzAwPlJ9WjXUWwt3653Fe7VkV6aufG2J/ti3ue7t31K+XuZ1YvtydcW/Ba0iAtS3VUPT6gDgughBcFqGYWh1SrYmL03RvO1Hqu7BaBURoDv6xGn0pY1pNQxJ1dtsH8op0her0/T5mv06ekqb7SvaRermHrHqc7LN9onSci3acVSzNh/S/O0ZKiotr3q+FuH+J4NPI6e/MRyoTT42Dz0yuI2u7tREE2YkafHOo/rvwt36dsNBPTUyXoPjI+t8iVxZuV0fLU+VVHEvkDMt0QPgOghBcDolZXb9sOWQJi9N0daDv7Yc7tc6XHf0idNlrRryjx7OqlEDXz0yuI3uv6KVfkqqaLO9Ym+W5m07onnbKtpst28crEU7jqrgZBdBSWoa6qcRHaI1smMjtY0KZIwBp2jW0F8f3dZVP207oqdnbtPBnCLd/ek69W8TromjEup0lnRu0hEdzClSqL+XxlzauM6uC6B+IQTBaeQUlmjKqjR9siJVR/KKJUnenlZd3amxbu8dp1bc+IoasHlYNbxDtIZ3iNbujHx9tjJN09ZXtNnel1Wxf1SjYB8N7xCtER0aqUOTYIIP8DssFouGJETpslYN9ebC3frfL3u1cMdRLXv1F/2pXwv9+fIWdTI7//7Jttg3dW/KagAAF4wQBFOVlNmVknlcn6xI1bT1B3SitOJejPBAb93SI1Y39oil5TAuWsuIQE0claC/XlnRZnt/dpEubxOuTk1D6CII1JCfl6f+MqStru7URBNnJGnJrkz9Z/4ufbvhgCaOTNAV7SJr7drr045pQ1qOvDysuqlnbK1dB0D9RwiCwxWXlSuzoESZ+cXKLKj8KNHR/GIdLSg+5XiJcotKq31tfHSQ7ugTpxEdo+XtyW/44FiVbbYBXLwW4QH65PZumr31sJ6ZtU37s4t0x8drNbBdhCaMTFBMqJ/Drzl5aYokaWTHRjTEAXBRCEE4LydKy6uCS+YZwszRyrCTX6y8E2XnfsJT2DwsJ+/3aa4ezUNZkgQALsJisWhY+2j1ax2u/yzYpclLUvTz9gwt2ZWpe/u31B/7NnfYkrWDOUWas/WwJNpiA7h4hCA3dqK0/DezMyWnzNwU62j+r6Env7jmwaZhgPfJD6+K/wZWfB4eWHEs/OTjwb42liQBgAvz9/bU40Pb6brOTfTkd0lasTdLr8zbqenrD2jiqARd3ibioq/x8fJUldsN9WoRxp5wAC4aIaieKSwpU2b+KTMzBcUnPz+hzPySasvTCmoYbLw8rBWBpjLMBHirYaDXKWHHW+EnPw/2tTGjAwBupmVEoKbe1V0zN6frn7O2KTWrULd+uEZDEiL15Ih4NQm5sCVyBcVl+nxVmiRmgQA4BiHIBRwvLqs2O3P0DPfbVD5WWFJ+7ic8hZen9WSY8VZ4gFf12ZtqMzfeCvLxJNgAAH6XxWLRqI6NNKBthF7/eac+WJaquUlHtHjnUd0/oJXuvCyuxvd8fr12v/KLy9S8ob/6O2BWCQAIQSYwDEPHS8pPLjf79d6ao6eEmVNncU7dxPF8+NisZ5ydqQwzp4acQG+CDQDA8QK8PfWP4fG6tnOMnvx+q1anZOvfc3do2roDmnRVgi5rFX5ez1NuN/ThslRJ0m29m7F8GoBDEIIcxDAMFZVJKZnHlXPCflqYOZpf/X6bylbQ58vX5lG19Cz81PtrznC/jb+XB8EGAOAU2kQF6ss/9tD3Gw/pnz9s197M47p58moNbx+tJ0a0U3Sw7+9+/YLko0rLLlSwr03XdG5SR1UDqO8IQQ7ypykbtWCHp7Rm2Xl/jZ+XxymzM6csRQusCDrhp9xv4+/NtwoA4JosFotGX9pYA9pF6NV5O/Xx8lT9sCVdC3dk6IErWun23nHy8rSe8Ws/WJ4qSRrXvan8vPi3EIBj8NPEQYL9bJIkf2+Pqq5nDU82DggP8KnWQKCyoQA/zAEA7iTIx6YJIxN0XecYPfX9Vq3dd0zPz07WN+sO6OlRCerVsmG18/cXSGv35cjTatH4ns3MKRpAvcS7cAd5Ymgb9bKlafTIwbLZbGaXAwCA04pvFKSv7u6p6RsO6rkft2t3RoHGvb9KIzs20j+GtVNUcMVGqAvTK2aHhneIrjoGAI5w5rln1FiQr01ejtkPDgCAes9qtejazk204LHLNb5nrKwWaeamQ7ri5UV6f8leHThWpA1ZFfe30hYbgKMRggAAgGmCfW2adFWiZtzXR5c2baDjJeX65w/bNfy/y2U3LOoS20AdmjQwu0wA9QwhCAAAmC6xcbCm/amXXrymg0L9var2vbutV6zJlQGoj7gnCAAAOAWr1aKxXWM0OCFS/12wS3v37NUVbdkcFYDjMRMEAACcSgM/L/1tSGtd1cwuDzZHBVALCEEAAAAA3AohCAAAAIBbIQQBAAAAcCuEIAAAAABuhRAEAAAAwK0QggAAAAC4FUIQAAAAALdCCAIAAADgVghBAAAAANwKIQgAAACAWyEEAQAAAHArhCAAAAAAboUQBAAAAMCtEIIAAAAAuBVCEAAAAAC3QggCAAAA4FYIQQAAAADcCiEIAAAAgFvxNLuAi2EYhiQpLy/P5Eqk0tJSFRYWKi8vTzabzexy4AYYc6hrjDnUJcYb6hpjzvVVZoLKjPB7XDoE5efnS5JiYmJMrgQAAACAM8jPz1dwcPDvnmMxzicqOSm73a5Dhw4pMDBQFovF1Fry8vIUExOj/fv3KygoyNRa4B4Yc6hrjDnUJcYb6hpjzvUZhqH8/Hw1atRIVuvv3/Xj0jNBVqtVTZo0MbuMaoKCgviLgzrFmENdY8yhLjHeUNcYc67tXDNAlWiMAAAAAMCtEIIAAAAAuBVCkIN4e3trwoQJ8vb2NrsUuAnGHOoaYw51ifGGusaYcy8u3RgBAAAAAGqKmSAAAAAAboUQBAAAAMCtEIIAAAAAuBVCEAAAAAC3Qgg6xXPPPaeuXbsqMDBQERERGj16tHbs2FHtnBMnTujee+9VWFiYAgICdM011+jIkSPVznnggQfUuXNneXt765JLLvnda+7evVuBgYFq0KCBg18NnF1djjfDMPTSSy+pdevW8vb2VuPGjfXss8/W1kuDk6rLMTd37lz16NFDgYGBCg8P1zXXXKPU1NRaemVwVo4Yc5s2bdINN9ygmJgY+fr6ql27dnr99ddPu9aiRYvUqVMneXt7q2XLlvroo49q++XBydTVeJs+fboGDRqk8PBwBQUFqWfPnpo7d26dvEY4DiHoFIsXL9a9996rlStXat68eSotLdXgwYN1/PjxqnMefvhhzZw5U19//bUWL16sQ4cO6eqrrz7tuW6//XZdf/31v3u90tJS3XDDDbrssssc/lrg/OpyvD344IN6//339dJLLyk5OVkzZsxQt27dauV1wXnV1ZhLSUnRVVddpQEDBmjjxo2aO3euMjMzz/g8qN8cMebWrVuniIgIffbZZ0pKStI//vEPPf744/rvf/9bdU5KSoqGDx+u/v37a+PGjXrooYd055138sbUzdTVePvll180aNAg/fjjj1q3bp369++vkSNHasOGDXX6enGRDJxVRkaGIclYvHixYRiGkZOTY9hsNuPrr7+uOmf79u2GJGPFihWnff2ECROMjh07nvX5//rXvxo33XST8eGHHxrBwcGOLh8uprbG27Zt2wxPT08jOTm51mqHa6qtMff1118bnp6eRnl5edWxGTNmGBaLxSgpKXH8C4HLuNgxV+nPf/6z0b9//6rP//rXvxoJCQnVzrn++uuNIUOGOPgVwJXU1ng7k/j4eGPSpEmOKRx1gpmg35GbmytJCg0NlVTx24HS0lINHDiw6py2bduqadOmWrFiRY2ee8GCBfr666/15ptvOq5guLTaGm8zZ85U8+bNNWvWLMXFxalZs2a68847lZ2d7dgXAJdTW2Ouc+fOslqt+vDDD1VeXq7c3Fx9+umnGjhwoGw2m2NfBFyKo8Zcbm5u1XNI0ooVK6o9hyQNGTKkxv82o36prfH2W3a7Xfn5+b97DpwPIegs7Ha7HnroIfXu3VuJiYmSpMOHD8vLy+u0+3ciIyN1+PDh837urKws3Xrrrfroo48UFBTkyLLhompzvO3du1f79u3T119/rU8++UQfffSR1q1bp2uvvdaRLwEupjbHXFxcnH766Sf9/e9/l7e3txo0aKADBw7oq6++cuRLgItx1Jhbvny5vvzyS/3xj3+sOnb48GFFRkae9hx5eXkqKipy7AuBS6jN8fZbL730kgoKCjR27FiH1Y/a52l2Ac7q3nvv1datW7V06VKHP/ddd92lcePGqW/fvg5/brim2hxvdrtdxcXF+uSTT9S6dWtJ0uTJk9W5c2ft2LFDbdq0cfg14fxqc8wdPnxYd911l8aPH68bbrhB+fn5euqpp3Tttddq3rx5slgsDr8mnJ8jxtzWrVt11VVXacKECRo8eLADq0N9U1fjberUqZo0aZK+//57RUREXPC1UPeYCTqD++67T7NmzdLChQvVpEmTquNRUVEqKSlRTk5OtfOPHDmiqKio837+BQsW6KWXXpKnp6c8PT11xx13KDc3V56envrggw8c9TLgImp7vEVHR8vT07MqAElSu3btJElpaWkXVzxcUm2PuTfffFPBwcF68cUXdemll6pv37767LPPNH/+fK1atcpRLwMuxBFjbtu2bbriiiv0xz/+UU888US1x6Kiok7rYnjkyBEFBQXJ19fXsS8GTq+2x1ulL774Qnfeeae++uqr05ZjwvkRgk5hGIbuu+8+ffvtt1qwYIHi4uKqPd65c2fZbDbNnz+/6tiOHTuUlpamnj17nvd1VqxYoY0bN1Z9PP300woMDNTGjRs1ZswYh70eOLe6Gm+9e/dWWVmZ9uzZU3Vs586dkqTY2NiLfBVwJXU15goLC2W1Vv/nxcPDQ1LFzCTch6PGXFJSkvr376/x48efsb1/z549qz2HJM2bN69G4xaur67GmyR9/vnnuu222/T5559r+PDhtfOCULtMbcvgZO655x4jODjYWLRokZGenl71UVhYWHXOn/70J6Np06bGggULjLVr1xo9e/Y0evbsWe15du3aZWzYsMG4++67jdatWxsbNmwwNmzYYBQXF5/xunSHc091Nd7Ky8uNTp06GX379jXWr19vrF271ujevbsxaNCgOn29MF9djbn58+cbFovFmDRpkrFz505j3bp1xpAhQ4zY2Nhq10L954gxt2XLFiM8PNy46aabqj1HRkZG1Tl79+41/Pz8jL/85S/G9u3bjTfffNPw8PAw5syZU6evF+aqq/E2ZcoUw9PT03jzzTernZOTk1OnrxcXhxB0Ckln/Pjwww+rzikqKjL+/Oc/GyEhIYafn58xZswYIz09vdrz9OvX74zPk5KScsbrEoLcU12Ot4MHDxpXX321ERAQYERGRhq33nqrkZWVVUevFM6iLsfc559/blx66aWGv7+/ER4ebowaNcrYvn17Hb1SOAtHjLkJEyac8TliY2OrXWvhwoXGJZdcYnh5eRnNmzevdg24h7oab2f7GTh+/Pi6e7G4aBbDMAzHzCkBAAAAgPPjniAAAAAAboUQBAAAAMCtEIIAAAAAuBVCEAAAAAC3QggCAAAA4FYIQQAAAADcCiEIAAAAgFshBAEAAABwK4QgAAAAAG6FEAQAcBqGYWjgwIEaMmTIaY+99dZbatCggQ4cOGBCZQCA+oQQBABwGhaLRR9++KFWrVqld999t+p4SkqK/vrXv+qNN95QkyZNHHrN0tJShz4fAMD5EYIAAE4lJiZGr7/+uh577DGlpKTIMAzdcccdGjx4sC699FINHTpUAQEBioyM1M0336zMzMyqr50zZ4769OmjBg0aKCwsTCNGjNCePXuqHk9NTZXFYtGXX36pfv36ycfHR1OmTDHjZQIATGQxDMMwuwgAAH5r9OjRys3N1dVXX61nnnlGSUlJSkhI0J133qlbbrlFRUVF+tvf/qaysjItWLBAkjRt2jRZLBZ16NBBBQUFeuqpp5SamqqNGzfKarUqNTVVcXFxatasmV5++WVdeuml8vHxUXR0tMmvFgBQlwhBAACnlJGRoYSEBGVnZ2vatGnaunWrlixZorlz51adc+DAAcXExGjHjh1q3br1ac+RmZmp8PBwbdmyRYmJiVUh6LXXXtODDz5Yly8HAOBEWA4HAHBKERERuvvuu9WuXTuNHj1amzZt0sKFCxUQEFD10bZtW0mqWvK2a9cu3XDDDWrevLmCgoLUrFkzSVJaWlq15+7SpUudvhYAgHPxNLsAAADOxtPTU56eFf9UFRQUaOTIkXrhhRdOO69yOdvIkSMVGxur9957T40aNZLdbldiYqJKSkqqne/v71/7xQMAnBYhCADgEjp16qRp06apWbNmVcHoVFlZWdqxY4fee+89XXbZZZKkpUuX1nWZAAAXwHI4AIBLuPfee5Wdna0bbrhBa9as0Z49ezR37lzddtttKi8vV0hIiMLCwvS///1Pu3fv1oIFC/TII4+YXTYAwAkRggAALqFRo0ZatmyZysvLNXjwYLVv314PPfSQGjRoIKvVKqvVqi+++ELr1q1TYmKiHn74Yf373/82u2wAgBOiOxwAAAAAt8JMEAAAAAC3QggCAAAA4FYIQQAAAADcCiEIAAAAgFshBAEAAABwK4QgAAAAAG6FEAQAAADArRCCAAAAALgVQhAAAAAAt0IIAgAAAOBWCEEAAAAA3Mr/A0VAtdI/K4eiAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# NBVAL_SKIP\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "\n", - "# Load data\n", - "df = pd.read_csv(\"/tmp/tmpvzjigv7g/n2OzlTWhinflation.csv\")\n", - "\n", - "# Calculate average yearly inflation\n", - "df['Average'] = df[['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']].mean(axis=1)\n", - "\n", - "# Plot average yearly inflation as a time series\n", - "plt.figure(figsize=(10,6))\n", - "plt.plot(df['Year'], df['Average'])\n", - "plt.title('Average Yearly Inflation')\n", - "plt.xlabel('Year')\n", - "plt.ylabel('Average Inflation')\n", - "plt.grid(True)\n", - "plt.show()" - ] - }, { "cell_type": "markdown", "id": "jSfjNN9fMxtm", @@ -2078,7 +1401,7 @@ "id": "jSfjNN9fMxtm" }, "source": [ - "### 2.5. Using Model Context Protocol\n", + "### 2.4. Using Model Context Protocol\n", "\n", "In this example, we will show how tools hosted in an MCP server can be configured to be used by the model.\n", "\n", @@ -2089,7 +1412,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 15, "id": "67fDKVVpNuFb", "metadata": { "colab": { @@ -2103,14 +1426,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "Collecting colab-xterm\n", - " Downloading colab_xterm-0.2.0-py3-none-any.whl.metadata (1.2 kB)\n", - "Requirement already satisfied: ptyprocess~=0.7.0 in /usr/local/lib/python3.11/dist-packages (from colab-xterm) (0.7.0)\n", - "Requirement already satisfied: tornado>5.1 in /usr/local/lib/python3.11/dist-packages (from colab-xterm) (6.3.3)\n", - "Downloading colab_xterm-0.2.0-py3-none-any.whl (115 kB)\n", - "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/115.6 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m115.6/115.6 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", - "\u001b[?25hInstalling collected packages: colab-xterm\n", - "Successfully installed colab-xterm-0.2.0\n" + "Requirement already satisfied: colab-xterm in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (0.2.0)\n", + "Requirement already satisfied: ptyprocess~=0.7.0 in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (from colab-xterm) (0.7.0)\n", + "Requirement already satisfied: tornado>5.1 in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (from colab-xterm) (6.4.2)\n" ] } ], @@ -2122,7 +1440,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "giIA2M-ANUIM", "metadata": { "colab": { @@ -2470,33 +1788,14 @@ "id": "giIA2M-ANUIM", "outputId": "612c3487-1fd7-41ab-f65a-690b1325f46d" }, - "outputs": [ - { - "data": { - "text/plain": [ - "Launching Xterm..." - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": "\n (async () => {\n const url = new URL(await google.colab.kernel.proxyPort(10000, {'cache': true}));\n const iframe = document.createElement('iframe');\n iframe.src = url;\n iframe.setAttribute('width', '100%');\n iframe.setAttribute('height', '800');\n iframe.setAttribute('frameborder', 0);\n document.body.appendChild(iframe);\n })();\n ", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# NBVAL_SKIP\n", "%xterm\n", - "# touch /content/foo\n", - "# touch /content/bar\n", - "# npx -y supergateway --port 8000 --stdio 'npx -y @modelcontextprotocol/server-filesystem /content'" + "# touch /tmp/content/foo\n", + "# echo hello > /tmp/content/foo\n", + "# touch /tmp/content/bar\n", + "# npx -y supergateway --port 8000 --stdio 'npx -y @modelcontextprotocol/server-filesystem /tmp/content'" ] }, { @@ -2511,7 +1810,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 18, "id": "DwdKhQb1N295", "metadata": { "id": "DwdKhQb1N295" @@ -2519,7 +1818,7 @@ "outputs": [], "source": [ "# NBVAL_SKIP\n", - "from llama_stack_client.types.tool_group import McpEndpoint\n", + "from llama_stack_client.types.toolgroup_register_params import McpEndpoint\n", "client.toolgroups.register(\n", " toolgroup_id=\"mcp::filesystem\",\n", " provider_id=\"model-context-protocol\",\n", @@ -2529,7 +1828,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 19, "id": "ZZ5_vIkDOyAN", "metadata": { "colab": { @@ -2856,7 +2155,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 21, "id": "vttLbj_YO01f", "metadata": { "colab": { @@ -2870,21 +2169,46 @@ "name": "stdout", "output_type": "stream", "text": [ - "User> Hello\n", - "inference> None of the provided functions can be used to respond to a greeting.\n", - "User> list all the files /content\n", - "inference> {\"type\": \"function\", \"name\": \"list_directory\", \"parameters\": {\"path\": \"/content\"}}\n", - "tool_execution> Tool:list_directory Args:{'path': '/content'}\n", - "tool_execution> Tool:list_directory Response:{\"type\":\"text\",\"text\":\"[DIR] .config\\n[FILE] bar\\n[FILE] foo\\n[DIR] sample_data\"}\n", - "inference> {\"type\": \"function\", \"name\": \"list_directory\", \"parameters\": {\"path\": \"/content\"}}\n", - "tool_execution> Tool:list_directory Args:{'path': '/content'}\n", - "tool_execution> Tool:list_directory Response:{\"type\":\"text\",\"text\":\"[DIR] .config\\n[FILE] bar\\n[FILE] foo\\n[DIR] sample_data\"}\n", - "inference> The list of files in the /content directory is:\n", - "\n", - "[DIR] .config\n", - "[FILE] bar\n", - "[FILE] foo\n", - "[DIR] sample_data\n" + "\u001b[32mUser> Hello\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_allowed\u001b[0m\u001b[33m_direct\u001b[0m\u001b[33mories\u001b[0m\u001b[33m()]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_allowed_directories Args:{}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_allowed_directories Response:{\"type\":\"text\",\"text\":\"Allowed directories:\\n/tmp/content\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_directory Args:{'path': '/tmp/content'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m\"),\u001b[0m\u001b[33m create\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Access denied - path outside allowed directories: /tmp not in /tmp/content\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_allowed\u001b[0m\u001b[33m_direct\u001b[0m\u001b[33mories\u001b[0m\u001b[33m()]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_allowed_directories Args:{}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_allowed_directories Response:{\"type\":\"text\",\"text\":\"Allowed directories:\\n/tmp/content\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m/sub\u001b[0m\u001b[33mdir\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content/subdir'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp/content\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_directory Args:{'path': '/tmp/content'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:list_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_allowed\u001b[0m\u001b[33m_direct\u001b[0m\u001b[33mories\u001b[0m\u001b[33m()]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[30m\u001b[0m\u001b[32mUser> Whats written in /tmp/content/foo ?\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mread\u001b[0m\u001b[33m_file\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m/foo\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:read_file Args:{'path': '/tmp/content/foo'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:read_file Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp/content\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mwrite\u001b[0m\u001b[33m_file\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m/foo\u001b[0m\u001b[33m\",\u001b[0m\u001b[33m content\u001b[0m\u001b[33m=\"\u001b[0m\u001b[33mHello\u001b[0m\u001b[33m World\u001b[0m\u001b[33m!\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:write_file Args:{'path': '/tmp/content/foo', 'content': 'Hello World!'}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:write_file Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp/content\",\"annotations\":null}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[31m500: Internal server error: An unexpected error occurred.\u001b[0m\n" ] } ], @@ -2901,7 +2225,7 @@ ")\n", "user_prompts = [\n", " \"Hello\",\n", - " \"list all the files /content\",\n", + " \"Whats written in /tmp/content/foo ?\",\n", "]\n", "\n", "session_id = agent.create_session(\"test-session\")\n", @@ -2960,7 +2284,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 22, "id": "4iCO59kP20Zs", "metadata": { "colab": { @@ -2974,17 +2298,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mN\u001b[0m\u001b[36mBA\u001b[0m\u001b[36m Western\u001b[0m\u001b[36m Conference\u001b[0m\u001b[36m Finals\u001b[0m\u001b[36m \u001b[0m\u001b[36m202\u001b[0m\u001b[36m4\u001b[0m\u001b[36m teams\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mN\u001b[0m\u001b[36mBA\u001b[0m\u001b[36m Western\u001b[0m\u001b[36m Conference\u001b[0m\u001b[36m Finals\u001b[0m\u001b[36m \u001b[0m\u001b[36m202\u001b[0m\u001b[36m4\u001b[0m\u001b[36m teams\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'NBA Western Conference Finals 2024 teams'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\u00a0Reference\\u202f\\u00ae Baseball Football (college) Basketball (college) Hockey F\\u00fatbol Blog Stathead\\u202f\\u00ae Immaculate Grid\\u202f\\u00ae\", \"score\": 0.89030397, \"raw_content\": null}, {\"title\": \"2024 NBA Western Conference playoff bracket - Basketnews.com\", \"url\": \"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\", \"content\": \"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\", \"score\": 0.8473754, \"raw_content\": null}, {\"title\": \"NBA Conference Finals Schedule: Full List of Games & Results\", \"url\": \"https://www.si.com/nba/nba-conference-finals-schedule-full-list-of-games-results\", \"content\": \"NBA Conference Finals Schedule: Full List of Games & Results NBA Conference Finals Schedule: Full List of Games & Results With the Minnesota' Timberwolves' epic comeback victory over the Denver Nuggets in Game 7, the 2024 NBA conference finals matchups are set. The Timberwolves will face off against the Dallas Mavericks, who dispatched the No. 1 seed Oklahoma City Thunder in six games, for a seat in the NBA Finals. In the other conference, the Boston Celtics will take on the Indiana Pacers, who pulled off their own big Game 7 win at Madison Square Garden to advance. | GAME | Game 1 | Game 2 | Game 3 | Game 4 | GAME | Game 1 | Game 2 | Game 3 | Game 4\", \"score\": 0.7859175, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: 'This is special, coming from the West' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.7522497, \"raw_content\": null}, {\"title\": \"NBA Western Conference Finals 2024: Schedule, Dates, and More\", \"url\": \"https://www.sportinglad.com/basketball/nba/nba-western-conference-finals-2024-schedule-dates-and-more/\", \"content\": \"The NBA Western Conference Finals 2024 is set to be a basketball spectacle that promises high stakes, thrilling plays, and unforgettable moments. As the season narrows down to the finest teams in the West, fans and analysts alike are on the edge of their seats, anticipating each game.\", \"score\": 0.7443038, \"raw_content\": null}]}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\u00a0Reference\\u202f\\u00ae Baseball Football (college) Basketball (college) Hockey F\\u00fatbol Blog Stathead\\u202f\\u00ae Immaculate Grid\\u202f\\u00ae\", \"score\": 0.89030397, \"raw_content\": null}, {\"title\": \"NBA Standings - 2024-25 season - ESPN\", \"url\": \"https://www.espn.com/nba/standings\", \"content\": \"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children's Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries ('PENN').\", \"score\": 0.83549726, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) | NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: 'This is special, coming from the West' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.75312227, \"raw_content\": null}, {\"title\": \"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\", \"url\": \"https://www.nba.com/playoffs/2024?os=wtmbloozowcj&ref=app\", \"content\": \"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 (Ep. 25) Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston's NBA-record 18th championship. WE DID ITTTT!' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\", \"score\": 0.63234437, \"raw_content\": null}, {\"title\": \"2025 NBA Playoffs: Standings, bracket and clinching updates\", \"url\": \"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\", \"content\": \"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\"Access Content\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\", \"score\": 0.13435538, \"raw_content\": null}]}\u001b[0m\n", "\u001b[33minference> \u001b[0m\u001b[33mThe\u001b[0m\u001b[33m teams\u001b[0m\u001b[33m that\u001b[0m\u001b[33m played\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m NBA\u001b[0m\u001b[33m Western\u001b[0m\u001b[33m Conference\u001b[0m\u001b[33m Finals\u001b[0m\u001b[33m of\u001b[0m\u001b[33m \u001b[0m\u001b[33m202\u001b[0m\u001b[33m4\u001b[0m\u001b[33m were\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Dallas\u001b[0m\u001b[33m Mavericks\u001b[0m\u001b[33m and\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Minnesota\u001b[0m\u001b[33m Timber\u001b[0m\u001b[33mw\u001b[0m\u001b[33molves\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mSouth\u001b[0m\u001b[36m Park\u001b[0m\u001b[36m Bill\u001b[0m\u001b[36m Cosby\u001b[0m\u001b[36m episode\u001b[0m\u001b[36m season\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mSouth\u001b[0m\u001b[36m Park\u001b[0m\u001b[36m Bill\u001b[0m\u001b[36m Cosby\u001b[0m\u001b[36m episode\u001b[0m\u001b[36m season\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'South Park Bill Cosby episode season'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"South Park Bill Cosby episode season\", \"top_k\": [{\"title\": \"Trapper Keeper | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Trapper_Keeper\", \"content\": \"\\\"Trapper Keeper\\\" is the twelfth episode of Season Four and the 60th overall episode of South Park. It aired on November 15, 2000.[1] ... \\\"Bill Cosby\\\" then explains that the binder is a means to conquer the world in the future and wipe out all traces of humanity. \\\"Cosby\\\" himself is a cyborg from the future named BSM-471 with the task to destroy\", \"score\": 0.79369855, \"raw_content\": null}, {\"title\": \"Bill Cosby - South Park Archives - Cartman, Stan, Kenny, Kyle\", \"url\": \"https://southpark.wiki.gg/wiki/Bill_Cosby\", \"content\": \"Page Characters Other Characters All Characters Page information He first appear in the Season Five episode, \\\"Here Comes the Neighborhood\\\", as one of the wealthy African-Americans who move to South Park. Cosby (or a parody of him) also appears as the host of the show. \\\"Here Comes the Neighborhood\\\" - One of the many wealthy African-Americans who move to South Park. Pages that were created prior to August 2024 are from the South Park Archives Wiki.\", \"score\": 0.77589405, \"raw_content\": null}, {\"title\": \"Bill Cosby is Here to See You - South Park | South Park Studios US\", \"url\": \"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\", \"content\": \"01:56 It's Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde's performance and calls the Record Producer to try and fix it. 01:24 Lorde's Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac's hologram. 01:37 I've Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\", \"score\": 0.5331307, \"raw_content\": null}, {\"title\": \"Bill Cosby | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Bill_Cosby\", \"content\": \"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\", \"score\": 0.48323447, \"raw_content\": null}, {\"title\": \"Bill Cosby (BSM-471) - South Park Archives - Cartman, Stan, Kenny, Kyle\", \"url\": \"https://southpark.wiki.gg/wiki/Bill_Cosby_(BSM-471)\", \"content\": \"Background. After Cartman shows off his new Dawson's Creek Trapper Keeper Ultra Keeper Futura S 2000, the boys go on the bus only to find Bill Cosby along with them posing as a new 4th grade student. He claims to have been held back 10 years. He soon learns about Cartman's new device, and tries numerous times to get his hands on it.\", \"score\": 0.29126853, \"raw_content\": null}]}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mBill\u001b[0m\u001b[33m Cosby\u001b[0m\u001b[33m (\u001b[0m\u001b[33mBS\u001b[0m\u001b[33mM\u001b[0m\u001b[33m-\u001b[0m\u001b[33m471\u001b[0m\u001b[33m)\u001b[0m\u001b[33m first\u001b[0m\u001b[33m appears\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m episode\u001b[0m\u001b[33m \"\u001b[0m\u001b[33mTr\u001b[0m\u001b[33mapper\u001b[0m\u001b[33m Keeper\u001b[0m\u001b[33m\"\u001b[0m\u001b[33m (\u001b[0m\u001b[33mSeason\u001b[0m\u001b[33m \u001b[0m\u001b[33m4\u001b[0m\u001b[33m,\u001b[0m\u001b[33m Episode\u001b[0m\u001b[33m \u001b[0m\u001b[33m12\u001b[0m\u001b[33m)\u001b[0m\u001b[33m of\u001b[0m\u001b[33m South\u001b[0m\u001b[33m Park\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mAndrew\u001b[0m\u001b[36m Tate\u001b[0m\u001b[36m kick\u001b[0m\u001b[36mboxing\u001b[0m\u001b[36m name\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"South Park Bill Cosby episode season\", \"top_k\": [{\"title\": \"Bill Cosby | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Bill_Cosby\", \"content\": \"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\", \"score\": 0.48294178, \"raw_content\": null}, {\"title\": \"Stunning and Brave - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Stunning_and_Brave\", \"content\": \"South Park episode \\\"Stunning and Brave\\\" is the first episode in the nineteenth season of the American animated television series South Park. Cartman and others mount an 'anti-PC' assault on the fraternity house but Kyle interrupts it, publicly calling Jenner a hero and brave. IGN's Max Nicholson gave the episode a 7.8 out of 10 and stated \\\"South Park's latest episode took on political correctness with scathing wit and truly outrageous moments.\\\"[1] \\\"South Park: \\\"Stunning and Brave\\\" Review\\\". \\\"South Park: Stunning and Brave Review\\\". \\\"South Park: Stunning and Brave\\\". \\\"South Park premiere is 'Stunning and Brave'\\\". \\\"Stunning and Brave\\\" Full episode at South Park Studios South Park episodes\", \"score\": 0.21465065, \"raw_content\": null}, {\"title\": \"Here Comes the Neighborhood - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Here_Comes_the_Neighborhood\", \"content\": \"\\\"Here Comes the Neighborhood\\\" is the 12th episode of the fifth season of the animated television series South Park, and the 77th episode of the series overall. Despondent at his social estrangement, Token decides to arrange for dozens of rich people (who all happen to be black) such as Will Smith and Snoop Dogg to move into South Park, which leads to Mr. Garrison complaining about the \\\"richers\\\" in the town, which in turn leads to ire among the other, less affluent members of the community (who all happen to be white). \\\"Here Comes the Neighborhood,\\\" along with the thirteen other episodes from South Park: the Complete Fifth Season, was released on a three-disc DVD set in the United States on February 22, 2005. South Park: The Complete Fifth Season: \\\"Here Comes the Neighborhood\\\" (DVD Disc audio commentary). \\\"Here Comes the Neighborhood\\\" Full episode at South Park Studios\", \"score\": 0.19947985, \"raw_content\": null}, {\"title\": \"Trapper Keeper | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Trapper_Keeper\", \"content\": \"Trapper Keeper | South Park Archives | Fandom Episodes Episodes in: Episodes, Featured Article Winners, Season 4, Episodes Focusing On Cartman | Episode no. Episode 12 | | List of all South Park episodes | \\\"Trapper Keeper\\\" is the twelfth episode of Season Four and the 60th overall episode of South Park. Kyle takes a Dawson's Creek Trapper Keeper with him to school and is soon met by Cartman. Cartman brags about his Dawson's Creek Trapper Keeper Ultra Keeper Futura S 2000, of which shows off many features that far exceed Kyle's. \\u2191 Jump up to: 1.0 1.1 Trapper Keeper (Season 4, Episode 13). Episodes Episodes Focusing On Cartman Espa\\u00f1ol Fran\\u00e7ais Italiano Portugu\\u00eas do Brasil \\u4e2d\\u6587\", \"score\": 0.1287991, \"raw_content\": null}, {\"title\": \"\\\"South Park\\\" Trapper Keeper (TV Episode 2000) - IMDb\", \"url\": \"https://www.imdb.com/title/tt0705978/\", \"content\": \"Trapper Keeper is a very interesting south park episode.It spoofs plenty of classic sci-fi films such as The Terminator, 2001 A Space Odyssea and the 1988 anime classic Akira(great movie if you haven't seen it).The episode has Cartman with a Dawson's Creek Trapper Keeper.A trapper keeper seems to be a school supply(I have never heard of it before).Cartman's trapper keeper is very advanced in terms of technology, however a robot from the future has come to destroy it because the trapper keeper takes over the world and destroys humanity in the future.The Trapper Keeper turns into a big blob(like in Akira) and sucks Cartman in.It then roams South Park and the boys try to stop it.Meanwhile, Kyle's brother Ike starts kindergarten where Garrison is the teacher.They decide to have a vote for class president between Ike and a kid named Filmore.It turns into a heated debate!\", \"score\": 0.12658015, \"raw_content\": null}]}\u001b[0m\n", + "\u001b[33minference> \u001b[0m\u001b[33mBill\u001b[0m\u001b[33m Cosby\u001b[0m\u001b[33m first\u001b[0m\u001b[33m appears\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m episode\u001b[0m\u001b[33m \"\u001b[0m\u001b[33mTr\u001b[0m\u001b[33mapped\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Closet\u001b[0m\u001b[33m\"\u001b[0m\u001b[33m (\u001b[0m\u001b[33mSeason\u001b[0m\u001b[33m \u001b[0m\u001b[33m9\u001b[0m\u001b[33m,\u001b[0m\u001b[33m Episode\u001b[0m\u001b[33m \u001b[0m\u001b[33m12\u001b[0m\u001b[33m)\u001b[0m\u001b[33m of\u001b[0m\u001b[33m South\u001b[0m\u001b[33m Park\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", + "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mAndrew\u001b[0m\u001b[36m Tate\u001b[0m\u001b[36m kick\u001b[0m\u001b[36mboxing\u001b[0m\u001b[36m name\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'Andrew Tate kickboxing name'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"Andrew Tate kickboxing name\", \"top_k\": [{\"title\": \"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\", \"url\": \"https://biographywallah.com/andrew-tate-biography/\", \"content\": \"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old (as of 2024)NationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\", \"score\": 0.80698997, \"raw_content\": null}, {\"title\": \"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\", \"url\": \"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\", \"content\": \"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\u2019s life has been full of adventure.\", \"score\": 0.78194773, \"raw_content\": null}, {\"title\": \"Andrew Tate Bio, Wiki, Net Worth, Age, Family, MMA Career - Next Biography\", \"url\": \"https://www.nextbiography.com/andrew-tate/\", \"content\": \"Home \\u00bb Andrew Tate Bio, Wiki, Net Worth, Age, Family, MMA Career Andrew Tate is one of the most Googled people around the world. Before you cast your impression, keep reading to know more about Andrew Tate, the kickboxer, social media influencer, Big Brother contestant, and founder of \\u2018Hustlers University\\u2019. | Name | Andrew Tate | Who is Andrew Tate? Andrew Tate Career Andrew Tate Height & Weight Who is Andrew Tate? Andrew Tate is a British-American kickboxer, commentator, internet personality, and businessman. Andrew Tate Career Andrew Tate started his career as a kickboxer. Andrew Tate Height & Weight About us / Contact us / Disclaimer/ Privacy policy / Terms of Service\", \"score\": 0.73914057, \"raw_content\": null}, {\"title\": \"Andrew Tate (\\\"King Cobra\\\") | MMA Fighter Page - Tapology\", \"url\": \"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\", \"content\": \"Andrew Tate (\\\"King Cobra\\\") | MMA Fighter Page | Tapology Andrew \\\"King Cobra\\\" Tate Andrew Tate Name: Andrew Tate Height: 6'1\\\" (185cm) | Reach: Andrew Tate is ineligible for Tapology's regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\", \"score\": 0.6999322, \"raw_content\": null}, {\"title\": \"Andrew Tate's Kickboxing Career & Biography - MMA Full Contact\", \"url\": \"https://www.mmafullcontact.com/andrew-tate-kickboxing/\", \"content\": \"Andrew Tate's Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\u2019s upcoming match and Tate\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\", \"score\": 0.53050464, \"raw_content\": null}]}\u001b[0m\n", + "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"Andrew Tate kickboxing name\", \"top_k\": [{\"title\": \"Andrew Tate Height, Weight, Biography, Age, Wife ... - News Unzip\", \"url\": \"https://www.newsunzip.com/wiki/andrew-tate/\", \"content\": \"Andrew Tate aka King Cobra (Real Name: 'Emory Andrew Tate III', born 1 December 1986, Age: 36 Years) is a professional kickboxer, MMA fighter, internet. Monday , 10 March 2025 ... Andrew's Kickboxing and MMA Record Andrew Tate Net worth, Lifestyle & Cars Collection. Andrew is a millionaire businessman. He makes a lot of money from his\", \"score\": 0.85995835, \"raw_content\": null}, {\"title\": \"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\", \"url\": \"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\", \"content\": \"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\u2019s life has been full of adventure.\", \"score\": 0.78194773, \"raw_content\": null}, {\"title\": \"Andrew Tate (\\\"King Cobra\\\") | MMA Fighter Page - Tapology\", \"url\": \"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\", \"content\": \"Andrew Tate (\\\"King Cobra\\\") | MMA Fighter Page | Tapology Andrew \\\"King Cobra\\\" Tate Andrew Tate Name: Andrew Tate Height: 6'1\\\" (185cm) | Reach: Andrew Tate is ineligible for Tapology's regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\", \"score\": 0.6999322, \"raw_content\": null}, {\"title\": \"Andrew Tate: Kickboxing Record, Facts, Height, Weight, Age, Biography\", \"url\": \"https://www.lowkickmma.com/andrew-tate-kickboxing-record-facts-height-weight-age-biography/\", \"content\": \"Who is Andrew Tate? Andrew Tate is a businessman, internet personality, and former professional kickboxer. Where is Andrew Tate From? Who is Andrew Tate\\u2019s Father? Andrew Tate Kickboxing Record What Kickboxing Gym Did Andrew Tate Train Out Of? How Many Professional Kickboxing Matches Has Andrew Tate Participated In? Andrew Tate competed in a total of 86 professional kickboxing bouts. What is Andrew Tate\\u2019 Professional Kickboxing Record? What Weight Classes Did Andrew Tate Compete In? In his professional kickboxing career, Andrew Tate won 32 of his fights by knockout. Did Andrew Tate Compete For Any Championship Titles? Did Tate Ever Compete In MMA? Andrew Tate competed in 1 professional MMA bout. How Much Money Did Andrew Tate Make In Kickboxing?\", \"score\": 0.50930125, \"raw_content\": null}, {\"title\": \"Andrew Tate - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Andrew_Tate\", \"content\": \"In 2011, Tate won his first International Sport Kickboxing Association (ISKA) world title in a rematch against Jean-Luc Beno\\u00eet via knockout, having previously lost to Beno\\u00eet by decision.[41] In 2012, Tate lost to Sahak Parparyan by unanimous decision while challenging for his It's Showtime 85MAX Championship.[42] Later that year, Tate lost the Enfusion championship tournament to Franci Graj\\u0161.[1] Before his loss, he was ranked second-best light-heavyweight kickboxer in the world.[43] In 2013, Tate won his second ISKA world title in a 12-round match against Vincent Petitjean, making him world champion in two weight divisions.[44] He defended the ISKA Belt and Won the Enfusion Belt in 2014, making him a four-time world champion[45] before he retired with 31 recorded fights.[46]\", \"score\": 0.49904844, \"raw_content\": null}]}\u001b[0m\n", "\u001b[33minference> \u001b[0m\u001b[33mAndrew\u001b[0m\u001b[33m Tate\u001b[0m\u001b[33m's\u001b[0m\u001b[33m kick\u001b[0m\u001b[33mboxing\u001b[0m\u001b[33m name\u001b[0m\u001b[33m is\u001b[0m\u001b[33m \"\u001b[0m\u001b[33mKing\u001b[0m\u001b[33m Cobra\u001b[0m\u001b[33m\".\u001b[0m\u001b[97m\u001b[0m\n", "\u001b[30m\u001b[0m" ] @@ -2996,7 +2320,7 @@ "agent = Agent(\n", " client, \n", " model=\"meta-llama/Llama-3.3-70B-Instruct\",\n", - " instructions=\"You are a helpful assistant. Use search tool to answer the questions. \",\n", + " instructions=\"You are a helpful assistant. Use web_search tool to answer the questions.\",\n", " tools=[\"builtin::websearch\"],\n", ")\n", "user_prompts = [\n", @@ -3005,7 +2329,7 @@ " \"What is the British-American kickboxer Andrew Tate's kickboxing name? Search the web for the answer.\",\n", "]\n", "\n", - "session_id = agent.create_session(\"test-session\")\n", + "session_id = agent.create_session(uuid.uuid4().hex)\n", "\n", "for prompt in user_prompts:\n", " response = agent.create_turn(\n", @@ -3034,506 +2358,25 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "c28ea2d1", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Session(\n",
-              "session_id='61d2486a-da18-4f25-8591-c757a8b2b84b',\n",
-              "session_name='test-session',\n",
-              "started_at=datetime.datetime(2025, 2, 26, 15, 28, 21, 189390),\n",
-              "turns=[\n",
-              "│   │   Turn(\n",
-              "│   │   │   input_messages=[\n",
-              "│   │   │   │   UserMessage(\n",
-              "│   │   │   │   │   content='Which teams played in the NBA western conference finals of 2024. Search the web for the answer.',\n",
-              "│   │   │   │   │   role='user',\n",
-              "│   │   │   │   │   context=None\n",
-              "│   │   │   │   )\n",
-              "│   │   │   ],\n",
-              "│   │   │   output_message=CompletionMessage(\n",
-              "│   │   │   │   content='The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.',\n",
-              "│   │   │   │   role='assistant',\n",
-              "│   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   tool_calls=[]\n",
-              "│   │   │   ),\n",
-              "│   │   │   session_id='61d2486a-da18-4f25-8591-c757a8b2b84b',\n",
-              "│   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 21, 195989, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=57600))),\n",
-              "│   │   │   steps=[\n",
-              "│   │   │   │   InferenceStep(\n",
-              "│   │   │   │   │   api_model_response=CompletionMessage(\n",
-              "│   │   │   │   │   │   content='',\n",
-              "│   │   │   │   │   │   role='assistant',\n",
-              "│   │   │   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   │   │   tool_calls=[\n",
-              "│   │   │   │   │   │   │   ToolCall(\n",
-              "│   │   │   │   │   │   │   │   arguments={'query': 'NBA Western Conference Finals 2024 teams'},\n",
-              "│   │   │   │   │   │   │   │   call_id='58cabb85-673e-499f-85d4-caefcc8d68ba',\n",
-              "│   │   │   │   │   │   │   │   tool_name='brave_search'\n",
-              "│   │   │   │   │   │   │   )\n",
-              "│   │   │   │   │   │   ]\n",
-              "│   │   │   │   │   ),\n",
-              "│   │   │   │   │   step_id='e28db61d-3cd0-4b83-93c5-af7df673a8c5',\n",
-              "│   │   │   │   │   step_type='inference',\n",
-              "│   │   │   │   │   turn_id='2c478207-8183-45e7-bea5-dcdef0cd2dce',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 23, 101607, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 21, 197826, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   ),\n",
-              "│   │   │   │   ToolExecutionStep(\n",
-              "│   │   │   │   │   step_id='15871a45-e10b-45a7-a5ad-2dd206504bca',\n",
-              "│   │   │   │   │   step_type='tool_execution',\n",
-              "│   │   │   │   │   tool_calls=[\n",
-              "│   │   │   │   │   │   ToolCall(\n",
-              "│   │   │   │   │   │   │   arguments={'query': 'NBA Western Conference Finals 2024 teams'},\n",
-              "│   │   │   │   │   │   │   call_id='58cabb85-673e-499f-85d4-caefcc8d68ba',\n",
-              "│   │   │   │   │   │   │   tool_name='brave_search'\n",
-              "│   │   │   │   │   │   )\n",
-              "│   │   │   │   │   ],\n",
-              "│   │   │   │   │   tool_responses=[\n",
-              "│   │   │   │   │   │   ToolResponse(\n",
-              "│   │   │   │   │   │   │   call_id='58cabb85-673e-499f-85d4-caefcc8d68ba',\n",
-              "│   │   │   │   │   │   │   content='{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7   Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\\\u00a0Reference\\\\u202f\\\\u00ae Baseball Football (college) Basketball (college) Hockey F\\\\u00fatbol Blog Stathead\\\\u202f\\\\u00ae Immaculate Grid\\\\u202f\\\\u00ae\", \"score\": 0.89030397, \"raw_content\": null}, {\"title\": \"2024 NBA Western Conference playoff bracket - Basketnews.com\", \"url\": \"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\", \"content\": \"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\", \"score\": 0.8473754, \"raw_content\": null}, {\"title\": \"NBA Conference Finals Schedule: Full List of Games & Results\", \"url\": \"https://www.si.com/nba/nba-conference-finals-schedule-full-list-of-games-results\", \"content\": \"NBA Conference Finals Schedule: Full List of Games & Results NBA Conference Finals Schedule: Full List of Games & Results With the Minnesota\\' Timberwolves\\' epic comeback victory over the Denver Nuggets in Game 7, the 2024 NBA conference finals matchups are set. The Timberwolves will face off against the Dallas Mavericks, who dispatched the No. 1 seed Oklahoma City Thunder in six games, for a seat in the NBA Finals. In the other conference, the Boston Celtics will take on the Indiana Pacers, who pulled off their own big Game 7 win at Madison Square Garden to advance. | GAME | Game 1 | Game 2 | Game 3 | Game 4 | GAME | Game 1 | Game 2 | Game 3 | Game 4\", \"score\": 0.7859175, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: \\'This is special, coming from the West\\' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.7522497, \"raw_content\": null}, {\"title\": \"NBA Western Conference Finals 2024: Schedule, Dates, and More\", \"url\": \"https://www.sportinglad.com/basketball/nba/nba-western-conference-finals-2024-schedule-dates-and-more/\", \"content\": \"The NBA Western Conference Finals 2024 is set to be a basketball spectacle that promises high stakes, thrilling plays, and unforgettable moments. As the season narrows down to the finest teams in the West, fans and analysts alike are on the edge of their seats, anticipating each game.\", \"score\": 0.7443038, \"raw_content\": null}]}',\n",
-              "│   │   │   │   │   │   │   tool_name='brave_search',\n",
-              "│   │   │   │   │   │   │   metadata=None\n",
-              "│   │   │   │   │   │   )\n",
-              "│   │   │   │   │   ],\n",
-              "│   │   │   │   │   turn_id='2c478207-8183-45e7-bea5-dcdef0cd2dce',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 25, 507599, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 23, 102744, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   ),\n",
-              "│   │   │   │   InferenceStep(\n",
-              "│   │   │   │   │   api_model_response=CompletionMessage(\n",
-              "│   │   │   │   │   │   content='The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.',\n",
-              "│   │   │   │   │   │   role='assistant',\n",
-              "│   │   │   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   │   │   tool_calls=[]\n",
-              "│   │   │   │   │   ),\n",
-              "│   │   │   │   │   step_id='b7fe26b7-9759-456f-af90-0f5f44797b98',\n",
-              "│   │   │   │   │   step_type='inference',\n",
-              "│   │   │   │   │   turn_id='2c478207-8183-45e7-bea5-dcdef0cd2dce',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 26, 90563, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 25, 509026, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   )\n",
-              "│   │   │   ],\n",
-              "│   │   │   turn_id='2c478207-8183-45e7-bea5-dcdef0cd2dce',\n",
-              "│   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 26, 91365, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   output_attachments=[]\n",
-              "│   │   ),\n",
-              "│   │   Turn(\n",
-              "│   │   │   input_messages=[\n",
-              "│   │   │   │   UserMessage(\n",
-              "│   │   │   │   │   content='In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title. Search the web for the answer.',\n",
-              "│   │   │   │   │   role='user',\n",
-              "│   │   │   │   │   context=None\n",
-              "│   │   │   │   )\n",
-              "│   │   │   ],\n",
-              "│   │   │   output_message=CompletionMessage(\n",
-              "│   │   │   │   content='Bill Cosby (BSM-471) first appears in the episode \"Trapper Keeper\" (Season 4, Episode 12) of South Park.',\n",
-              "│   │   │   │   role='assistant',\n",
-              "│   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   tool_calls=[]\n",
-              "│   │   │   ),\n",
-              "│   │   │   session_id='61d2486a-da18-4f25-8591-c757a8b2b84b',\n",
-              "│   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 26, 108327, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=57600))),\n",
-              "│   │   │   steps=[\n",
-              "│   │   │   │   InferenceStep(\n",
-              "│   │   │   │   │   api_model_response=CompletionMessage(\n",
-              "│   │   │   │   │   │   content='',\n",
-              "│   │   │   │   │   │   role='assistant',\n",
-              "│   │   │   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   │   │   tool_calls=[\n",
-              "│   │   │   │   │   │   │   ToolCall(\n",
-              "│   │   │   │   │   │   │   │   arguments={'query': 'South Park Bill Cosby episode season'},\n",
-              "│   │   │   │   │   │   │   │   call_id='496a2a83-53a3-408e-914a-8d58f7a2d1b0',\n",
-              "│   │   │   │   │   │   │   │   tool_name='brave_search'\n",
-              "│   │   │   │   │   │   │   )\n",
-              "│   │   │   │   │   │   ]\n",
-              "│   │   │   │   │   ),\n",
-              "│   │   │   │   │   step_id='79969675-3f43-496e-948d-332b34768f1d',\n",
-              "│   │   │   │   │   step_type='inference',\n",
-              "│   │   │   │   │   turn_id='4333b04a-020e-411e-8be3-ff81b6bf18a3',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 26, 713679, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 26, 115778, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   ),\n",
-              "│   │   │   │   ToolExecutionStep(\n",
-              "│   │   │   │   │   step_id='fabca5ea-f997-48a9-996b-150476b84dea',\n",
-              "│   │   │   │   │   step_type='tool_execution',\n",
-              "│   │   │   │   │   tool_calls=[\n",
-              "│   │   │   │   │   │   ToolCall(\n",
-              "│   │   │   │   │   │   │   arguments={'query': 'South Park Bill Cosby episode season'},\n",
-              "│   │   │   │   │   │   │   call_id='496a2a83-53a3-408e-914a-8d58f7a2d1b0',\n",
-              "│   │   │   │   │   │   │   tool_name='brave_search'\n",
-              "│   │   │   │   │   │   )\n",
-              "│   │   │   │   │   ],\n",
-              "│   │   │   │   │   tool_responses=[\n",
-              "│   │   │   │   │   │   ToolResponse(\n",
-              "│   │   │   │   │   │   │   call_id='496a2a83-53a3-408e-914a-8d58f7a2d1b0',\n",
-              "│   │   │   │   │   │   │   content='{\"query\": \"South Park Bill Cosby episode season\", \"top_k\": [{\"title\": \"Trapper Keeper | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Trapper_Keeper\", \"content\": \"\\\\\"Trapper Keeper\\\\\" is the twelfth episode of Season Four and the 60th overall episode of South Park. It aired on November 15, 2000.[1] ... \\\\\"Bill Cosby\\\\\" then explains that the binder is a means to conquer the world in the future and wipe out all traces of humanity. \\\\\"Cosby\\\\\" himself is a cyborg from the future named BSM-471 with the task to destroy\", \"score\": 0.79369855, \"raw_content\": null}, {\"title\": \"Bill Cosby - South Park Archives - Cartman, Stan, Kenny, Kyle\", \"url\": \"https://southpark.wiki.gg/wiki/Bill_Cosby\", \"content\": \"Page Characters Other Characters All Characters Page information He first appear in the Season Five episode, \\\\\"Here Comes the Neighborhood\\\\\", as one of the wealthy African-Americans who move to South Park. Cosby (or a parody of him) also appears as the host of the show. \\\\\"Here Comes the Neighborhood\\\\\" - One of the many wealthy African-Americans who move to South Park. Pages that were created prior to August 2024 are from the South Park Archives Wiki.\", \"score\": 0.77589405, \"raw_content\": null}, {\"title\": \"Bill Cosby is Here to See You - South Park | South Park Studios US\", \"url\": \"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\", \"content\": \"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\", \"score\": 0.5331307, \"raw_content\": null}, {\"title\": \"Bill Cosby | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Bill_Cosby\", \"content\": \"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\", \"score\": 0.48323447, \"raw_content\": null}, {\"title\": \"Bill Cosby (BSM-471) - South Park Archives - Cartman, Stan, Kenny, Kyle\", \"url\": \"https://southpark.wiki.gg/wiki/Bill_Cosby_(BSM-471)\", \"content\": \"Background. After Cartman shows off his new Dawson\\'s Creek Trapper Keeper Ultra Keeper Futura S 2000, the boys go on the bus only to find Bill Cosby along with them posing as a new 4th grade student. He claims to have been held back 10 years. He soon learns about Cartman\\'s new device, and tries numerous times to get his hands on it.\", \"score\": 0.29126853, \"raw_content\": null}]}',\n",
-              "│   │   │   │   │   │   │   tool_name='brave_search',\n",
-              "│   │   │   │   │   │   │   metadata=None\n",
-              "│   │   │   │   │   │   )\n",
-              "│   │   │   │   │   ],\n",
-              "│   │   │   │   │   turn_id='4333b04a-020e-411e-8be3-ff81b6bf18a3',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 28, 892613, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 26, 715724, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   ),\n",
-              "│   │   │   │   InferenceStep(\n",
-              "│   │   │   │   │   api_model_response=CompletionMessage(\n",
-              "│   │   │   │   │   │   content='Bill Cosby (BSM-471) first appears in the episode \"Trapper Keeper\" (Season 4, Episode 12) of South Park.',\n",
-              "│   │   │   │   │   │   role='assistant',\n",
-              "│   │   │   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   │   │   tool_calls=[]\n",
-              "│   │   │   │   │   ),\n",
-              "│   │   │   │   │   step_id='ca503c6f-e3ad-4eda-a114-fe64f89bc080',\n",
-              "│   │   │   │   │   step_type='inference',\n",
-              "│   │   │   │   │   turn_id='4333b04a-020e-411e-8be3-ff81b6bf18a3',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 31, 844729, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 28, 895798, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   )\n",
-              "│   │   │   ],\n",
-              "│   │   │   turn_id='4333b04a-020e-411e-8be3-ff81b6bf18a3',\n",
-              "│   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 31, 845596, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   output_attachments=[]\n",
-              "│   │   ),\n",
-              "│   │   Turn(\n",
-              "│   │   │   input_messages=[\n",
-              "│   │   │   │   UserMessage(\n",
-              "│   │   │   │   │   content=\"What is the British-American kickboxer Andrew Tate's kickboxing name? Search the web for the answer.\",\n",
-              "│   │   │   │   │   role='user',\n",
-              "│   │   │   │   │   context=None\n",
-              "│   │   │   │   )\n",
-              "│   │   │   ],\n",
-              "│   │   │   output_message=CompletionMessage(\n",
-              "│   │   │   │   content='Andrew Tate\\'s kickboxing name is \"King Cobra\".',\n",
-              "│   │   │   │   role='assistant',\n",
-              "│   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   tool_calls=[]\n",
-              "│   │   │   ),\n",
-              "│   │   │   session_id='61d2486a-da18-4f25-8591-c757a8b2b84b',\n",
-              "│   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 31, 854184, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=57600))),\n",
-              "│   │   │   steps=[\n",
-              "│   │   │   │   InferenceStep(\n",
-              "│   │   │   │   │   api_model_response=CompletionMessage(\n",
-              "│   │   │   │   │   │   content='',\n",
-              "│   │   │   │   │   │   role='assistant',\n",
-              "│   │   │   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   │   │   tool_calls=[\n",
-              "│   │   │   │   │   │   │   ToolCall(\n",
-              "│   │   │   │   │   │   │   │   arguments={'query': 'Andrew Tate kickboxing name'},\n",
-              "│   │   │   │   │   │   │   │   call_id='9a730927-bf56-4400-b694-38f28eda1065',\n",
-              "│   │   │   │   │   │   │   │   tool_name='brave_search'\n",
-              "│   │   │   │   │   │   │   )\n",
-              "│   │   │   │   │   │   ]\n",
-              "│   │   │   │   │   ),\n",
-              "│   │   │   │   │   step_id='f4288e1d-21e6-4695-949c-c55e660f31bf',\n",
-              "│   │   │   │   │   step_type='inference',\n",
-              "│   │   │   │   │   turn_id='7928703a-48d6-4251-a9ca-03a8f50366c2',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 33, 550463, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 31, 854908, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   ),\n",
-              "│   │   │   │   ToolExecutionStep(\n",
-              "│   │   │   │   │   step_id='568b75c7-8bc1-4a61-99ad-bfb4dce6638e',\n",
-              "│   │   │   │   │   step_type='tool_execution',\n",
-              "│   │   │   │   │   tool_calls=[\n",
-              "│   │   │   │   │   │   ToolCall(\n",
-              "│   │   │   │   │   │   │   arguments={'query': 'Andrew Tate kickboxing name'},\n",
-              "│   │   │   │   │   │   │   call_id='9a730927-bf56-4400-b694-38f28eda1065',\n",
-              "│   │   │   │   │   │   │   tool_name='brave_search'\n",
-              "│   │   │   │   │   │   )\n",
-              "│   │   │   │   │   ],\n",
-              "│   │   │   │   │   tool_responses=[\n",
-              "│   │   │   │   │   │   ToolResponse(\n",
-              "│   │   │   │   │   │   │   call_id='9a730927-bf56-4400-b694-38f28eda1065',\n",
-              "│   │   │   │   │   │   │   content='{\"query\": \"Andrew Tate kickboxing name\", \"top_k\": [{\"title\": \"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\", \"url\": \"https://biographywallah.com/andrew-tate-biography/\", \"content\": \"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old (as of 2024)NationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\", \"score\": 0.80698997, \"raw_content\": null}, {\"title\": \"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\", \"url\": \"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\", \"content\": \"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\u2019s life has been full of adventure.\", \"score\": 0.78194773, \"raw_content\": null}, {\"title\": \"Andrew Tate Bio, Wiki, Net Worth, Age, Family, MMA Career - Next Biography\", \"url\": \"https://www.nextbiography.com/andrew-tate/\", \"content\": \"Home \\\\u00bb Andrew Tate Bio, Wiki, Net Worth, Age, Family, MMA Career Andrew Tate is one of the most Googled people around the world. Before you cast your impression, keep reading to know more about Andrew Tate, the kickboxer, social media influencer, Big Brother contestant, and founder of \\\\u2018Hustlers University\\\\u2019. | Name | Andrew Tate | Who is Andrew Tate? Andrew Tate Career Andrew Tate Height & Weight Who is Andrew Tate? Andrew Tate is a British-American kickboxer, commentator, internet personality, and businessman. Andrew Tate Career Andrew Tate started his career as a kickboxer. Andrew Tate Height & Weight About us / Contact us / Disclaimer/ Privacy policy / Terms of Service\", \"score\": 0.73914057, \"raw_content\": null}, {\"title\": \"Andrew Tate (\\\\\"King Cobra\\\\\") | MMA Fighter Page - Tapology\", \"url\": \"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\", \"content\": \"Andrew Tate (\\\\\"King Cobra\\\\\") | MMA Fighter Page | Tapology Andrew \\\\\"King Cobra\\\\\" Tate Andrew Tate Name: Andrew Tate Height: 6\\'1\\\\\" (185cm) | Reach: Andrew Tate is ineligible for Tapology\\'s regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\\\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\", \"score\": 0.6999322, \"raw_content\": null}, {\"title\": \"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact\", \"url\": \"https://www.mmafullcontact.com/andrew-tate-kickboxing/\", \"content\": \"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\\\u2019s upcoming match and Tate\\\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\", \"score\": 0.53050464, \"raw_content\": null}]}',\n",
-              "│   │   │   │   │   │   │   tool_name='brave_search',\n",
-              "│   │   │   │   │   │   │   metadata=None\n",
-              "│   │   │   │   │   │   )\n",
-              "│   │   │   │   │   ],\n",
-              "│   │   │   │   │   turn_id='7928703a-48d6-4251-a9ca-03a8f50366c2',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 35, 851029, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 33, 552479, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   ),\n",
-              "│   │   │   │   InferenceStep(\n",
-              "│   │   │   │   │   api_model_response=CompletionMessage(\n",
-              "│   │   │   │   │   │   content='Andrew Tate\\'s kickboxing name is \"King Cobra\".',\n",
-              "│   │   │   │   │   │   role='assistant',\n",
-              "│   │   │   │   │   │   stop_reason='end_of_turn',\n",
-              "│   │   │   │   │   │   tool_calls=[]\n",
-              "│   │   │   │   │   ),\n",
-              "│   │   │   │   │   step_id='f138e0ad-263e-45d4-b986-db82829b693a',\n",
-              "│   │   │   │   │   step_type='inference',\n",
-              "│   │   │   │   │   turn_id='7928703a-48d6-4251-a9ca-03a8f50366c2',\n",
-              "│   │   │   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 36, 688422, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   │   │   started_at=datetime.datetime(2025, 2, 26, 15, 28, 35, 853888, tzinfo=TzInfo(-08:00))\n",
-              "│   │   │   │   )\n",
-              "│   │   │   ],\n",
-              "│   │   │   turn_id='7928703a-48d6-4251-a9ca-03a8f50366c2',\n",
-              "│   │   │   completed_at=datetime.datetime(2025, 2, 26, 15, 28, 36, 689693, tzinfo=TzInfo(-08:00)),\n",
-              "│   │   │   output_attachments=[]\n",
-              "│   │   )\n",
-              "]\n",
-              ")\n",
-              "
\n" - ], - "text/plain": [ - "\u001b[1;35mSession\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33msession_id\u001b[0m=\u001b[32m'61d2486a-da18-4f25-8591-c757a8b2b84b'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33msession_name\u001b[0m=\u001b[32m'test-session'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m189390\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mturns\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mTurn\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33minput_messages\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mUserMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'Which teams played in the NBA western conference finals of 2024. Search the web for the answer.'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'user'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcontext\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moutput_message\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msession_id\u001b[0m=\u001b[32m'61d2486a-da18-4f25-8591-c757a8b2b84b'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m195989\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.timezone\u001b[0m\u001b[1m(\u001b[0m\u001b[1;35mdatetime.timedelta\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdays\u001b[0m=\u001b[1;36m-1\u001b[0m, \u001b[33mseconds\u001b[0m=\u001b[1;36m57600\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msteps\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mInferenceStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mapi_model_response\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m''\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[1;35mToolCall\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33marguments\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'query'\u001b[0m: \u001b[32m'NBA Western Conference Finals 2024 teams'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'58cabb85-673e-499f-85d4-caefcc8d68ba'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'e28db61d-3cd0-4b83-93c5-af7df673a8c5'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'inference'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'2c478207-8183-45e7-bea5-dcdef0cd2dce'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m23\u001b[0m, \u001b[1;36m101607\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m197826\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mToolExecutionStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'15871a45-e10b-45a7-a5ad-2dd206504bca'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'tool_execution'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mToolCall\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33marguments\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'query'\u001b[0m: \u001b[32m'NBA Western Conference Finals 2024 teams'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'58cabb85-673e-499f-85d4-caefcc8d68ba'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtool_responses\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mToolResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'58cabb85-673e-499f-85d4-caefcc8d68ba'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m4-1\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\\\u00a0Reference\\\\u202f\\\\u00ae Baseball Football \u001b[0m\u001b[32m(\u001b[0m\u001b[32mcollege\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Basketball \u001b[0m\u001b[32m(\u001b[0m\u001b[32mcollege\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Hockey F\\\\u00fatbol Blog Stathead\\\\u202f\\\\u00ae Immaculate Grid\\\\u202f\\\\u00ae\", \"score\": 0.89030397, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"2024 NBA Western Conference playoff bracket - Basketnews.com\", \"url\": \"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\", \"content\": \"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\", \"score\": 0.8473754, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"NBA Conference Finals Schedule: Full List of Games & Results\", \"url\": \"https://www.si.com/nba/nba-conference-finals-schedule-full-list-of-games-results\", \"content\": \"NBA Conference Finals Schedule: Full List of Games & Results NBA Conference Finals Schedule: Full List of Games & Results With the Minnesota\\' Timberwolves\\' epic comeback victory over the Denver Nuggets in Game 7, the 2024 NBA conference finals matchups are set. The Timberwolves will face off against the Dallas Mavericks, who dispatched the No. 1 seed Oklahoma City Thunder in six games, for a seat in the NBA Finals. In the other conference, the Boston Celtics will take on the Indiana Pacers, who pulled off their own big Game 7 win at Madison Square Garden to advance. | GAME | Game 1 | Game 2 | Game 3 | Game 4 | GAME | Game 1 | Game 2 | Game 3 | Game 4\", \"score\": 0.7859175, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: \\'This is special, coming from the West\\' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.7522497, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"NBA Western Conference Finals 2024: Schedule, Dates, and More\", \"url\": \"https://www.sportinglad.com/basketball/nba/nba-western-conference-finals-2024-schedule-dates-and-more/\", \"content\": \"The NBA Western Conference Finals 2024 is set to be a basketball spectacle that promises high stakes, thrilling plays, and unforgettable moments. As the season narrows down to the finest teams in the West, fans and analysts alike are on the edge of their seats, anticipating each game.\", \"score\": 0.7443038, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'2c478207-8183-45e7-bea5-dcdef0cd2dce'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m507599\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m23\u001b[0m, \u001b[1;36m102744\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mInferenceStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mapi_model_response\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'b7fe26b7-9759-456f-af90-0f5f44797b98'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'inference'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'2c478207-8183-45e7-bea5-dcdef0cd2dce'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m90563\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m509026\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'2c478207-8183-45e7-bea5-dcdef0cd2dce'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m91365\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moutput_attachments\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mTurn\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33minput_messages\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mUserMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title. Search the web for the answer.'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'user'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcontext\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moutput_message\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appears in the episode \"Trapper Keeper\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 4, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msession_id\u001b[0m=\u001b[32m'61d2486a-da18-4f25-8591-c757a8b2b84b'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m108327\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.timezone\u001b[0m\u001b[1m(\u001b[0m\u001b[1;35mdatetime.timedelta\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdays\u001b[0m=\u001b[1;36m-1\u001b[0m, \u001b[33mseconds\u001b[0m=\u001b[1;36m57600\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msteps\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mInferenceStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mapi_model_response\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m''\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[1;35mToolCall\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33marguments\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'query'\u001b[0m: \u001b[32m'South Park Bill Cosby episode season'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'496a2a83-53a3-408e-914a-8d58f7a2d1b0'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'79969675-3f43-496e-948d-332b34768f1d'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'inference'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'4333b04a-020e-411e-8be3-ff81b6bf18a3'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m713679\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m115778\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mToolExecutionStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'fabca5ea-f997-48a9-996b-150476b84dea'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'tool_execution'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mToolCall\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33marguments\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'query'\u001b[0m: \u001b[32m'South Park Bill Cosby episode season'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'496a2a83-53a3-408e-914a-8d58f7a2d1b0'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtool_responses\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mToolResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'496a2a83-53a3-408e-914a-8d58f7a2d1b0'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\": \"South Park Bill Cosby episode season\", \"top_k\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Trapper Keeper | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Trapper_Keeper\", \"content\": \"\\\\\"Trapper Keeper\\\\\" is the twelfth episode of Season Four and the 60th overall episode of South Park. It aired on November 15, 2000.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m ... \\\\\"Bill Cosby\\\\\" then explains that the binder is a means to conquer the world in the future and wipe out all traces of humanity. \\\\\"Cosby\\\\\" himself is a cyborg from the future named BSM-471 with the task to destroy\", \"score\": 0.79369855, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Bill Cosby - South Park Archives - Cartman, Stan, Kenny, Kyle\", \"url\": \"https://southpark.wiki.gg/wiki/Bill_Cosby\", \"content\": \"Page Characters Other Characters All Characters Page information He first appear in the Season Five episode, \\\\\"Here Comes the Neighborhood\\\\\", as one of the wealthy African-Americans who move to South Park. Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mor a parody of him\u001b[0m\u001b[32m)\u001b[0m\u001b[32m also appears as the host of the show. \\\\\"Here Comes the Neighborhood\\\\\" - One of the many wealthy African-Americans who move to South Park. Pages that were created prior to August 2024 are from the South Park Archives Wiki.\", \"score\": 0.77589405, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Bill Cosby is Here to See You - South Park | South Park Studios US\", \"url\": \"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\", \"content\": \"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\", \"score\": 0.5331307, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Bill Cosby | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Bill_Cosby\", \"content\": \"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill \u001b[0m\u001b[32m(\u001b[0m\u001b[32mDisambiguation\u001b[0m\u001b[32m)\u001b[0m\u001b[32m. Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\", \"score\": 0.48323447, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - South Park Archives - Cartman, Stan, Kenny, Kyle\", \"url\": \"https://southpark.wiki.gg/wiki/Bill_Cosby_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\", \"content\": \"Background. After Cartman shows off his new Dawson\\'s Creek Trapper Keeper Ultra Keeper Futura S 2000, the boys go on the bus only to find Bill Cosby along with them posing as a new 4th grade student. He claims to have been held back 10 years. He soon learns about Cartman\\'s new device, and tries numerous times to get his hands on it.\", \"score\": 0.29126853, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'4333b04a-020e-411e-8be3-ff81b6bf18a3'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m892613\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m715724\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mInferenceStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mapi_model_response\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appears in the episode \"Trapper Keeper\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 4, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'ca503c6f-e3ad-4eda-a114-fe64f89bc080'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'inference'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'4333b04a-020e-411e-8be3-ff81b6bf18a3'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m31\u001b[0m, \u001b[1;36m844729\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m895798\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'4333b04a-020e-411e-8be3-ff81b6bf18a3'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m31\u001b[0m, \u001b[1;36m845596\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moutput_attachments\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mTurn\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33minput_messages\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mUserMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m\"What\u001b[0m\u001b[32m is the British-American kickboxer Andrew Tate's kickboxing name? Search the web for the answer.\"\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'user'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcontext\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moutput_message\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'Andrew Tate\\'s kickboxing name is \"King Cobra\".'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msession_id\u001b[0m=\u001b[32m'61d2486a-da18-4f25-8591-c757a8b2b84b'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m31\u001b[0m, \u001b[1;36m854184\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.timezone\u001b[0m\u001b[1m(\u001b[0m\u001b[1;35mdatetime.timedelta\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdays\u001b[0m=\u001b[1;36m-1\u001b[0m, \u001b[33mseconds\u001b[0m=\u001b[1;36m57600\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msteps\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mInferenceStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mapi_model_response\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m''\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[1;35mToolCall\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33marguments\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'query'\u001b[0m: \u001b[32m'Andrew Tate kickboxing name'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'9a730927-bf56-4400-b694-38f28eda1065'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'f4288e1d-21e6-4695-949c-c55e660f31bf'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'inference'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'7928703a-48d6-4251-a9ca-03a8f50366c2'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m33\u001b[0m, \u001b[1;36m550463\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m31\u001b[0m, \u001b[1;36m854908\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mToolExecutionStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'568b75c7-8bc1-4a61-99ad-bfb4dce6638e'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'tool_execution'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mToolCall\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33marguments\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'query'\u001b[0m: \u001b[32m'Andrew Tate kickboxing name'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'9a730927-bf56-4400-b694-38f28eda1065'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtool_responses\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mToolResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcall_id\u001b[0m=\u001b[32m'9a730927-bf56-4400-b694-38f28eda1065'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\": \"Andrew Tate kickboxing name\", \"top_k\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\", \"url\": \"https://biographywallah.com/andrew-tate-biography/\", \"content\": \"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old \u001b[0m\u001b[32m(\u001b[0m\u001b[32mas of 2024\u001b[0m\u001b[32m)\u001b[0m\u001b[32mNationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\", \"score\": 0.80698997, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"The Life Of Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBy Andrew Tate Himself ... - Sidekick Boxing\", \"url\": \"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\", \"content\": \"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\u2019s life has been full of adventure.\", \"score\": 0.78194773, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Andrew Tate Bio, Wiki, Net Worth, Age, Family, MMA Career - Next Biography\", \"url\": \"https://www.nextbiography.com/andrew-tate/\", \"content\": \"Home \\\\u00bb Andrew Tate Bio, Wiki, Net Worth, Age, Family, MMA Career Andrew Tate is one of the most Googled people around the world. Before you cast your impression, keep reading to know more about Andrew Tate, the kickboxer, social media influencer, Big Brother contestant, and founder of \\\\u2018Hustlers University\\\\u2019. | Name | Andrew Tate | Who is Andrew Tate? Andrew Tate Career Andrew Tate Height & Weight Who is Andrew Tate? Andrew Tate is a British-American kickboxer, commentator, internet personality, and businessman. Andrew Tate Career Andrew Tate started his career as a kickboxer. Andrew Tate Height & Weight About us / Contact us / Disclaimer/ Privacy policy / Terms of Service\", \"score\": 0.73914057, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\\"King Cobra\\\\\"\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | MMA Fighter Page - Tapology\", \"url\": \"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\", \"content\": \"Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\\"King Cobra\\\\\"\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | MMA Fighter Page | Tapology Andrew \\\\\"King Cobra\\\\\" Tate Andrew Tate Name: Andrew Tate Height: 6\\'1\\\\\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32m185cm\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | Reach: Andrew Tate is ineligible for Tapology\\'s regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\\\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\", \"score\": 0.6999322, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"title\": \"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact\", \"url\": \"https://www.mmafullcontact.com/andrew-tate-kickboxing/\", \"content\": \"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\\\u2019s upcoming match and Tate\\\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\", \"score\": 0.53050464, \"raw_content\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mtool_name\u001b[0m=\u001b[32m'brave_search'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'7928703a-48d6-4251-a9ca-03a8f50366c2'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m35\u001b[0m, \u001b[1;36m851029\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m33\u001b[0m, \u001b[1;36m552479\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mInferenceStep\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mapi_model_response\u001b[0m=\u001b[1;35mCompletionMessage\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mcontent\u001b[0m=\u001b[32m'Andrew Tate\\'s kickboxing name is \"King Cobra\".'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mrole\u001b[0m=\u001b[32m'assistant'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mstop_reason\u001b[0m=\u001b[32m'end_of_turn'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[33mtool_calls\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_id\u001b[0m=\u001b[32m'f138e0ad-263e-45d4-b986-db82829b693a'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstep_type\u001b[0m=\u001b[32m'inference'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'7928703a-48d6-4251-a9ca-03a8f50366c2'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m36\u001b[0m, \u001b[1;36m688422\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mstarted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m35\u001b[0m, \u001b[1;36m853888\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mturn_id\u001b[0m=\u001b[32m'7928703a-48d6-4251-a9ca-03a8f50366c2'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcompleted_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2025\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m26\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m36\u001b[0m, \u001b[1;36m689693\u001b[0m, \u001b[33mtzinfo\u001b[0m=\u001b[1;35mTzInfo\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m-08\u001b[0m:\u001b[1;36m00\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moutput_attachments\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# query the agents session\n", "from rich.pretty import pprint\n", + "\n", "session_response = client.agents.session.retrieve(\n", " session_id=session_id,\n", " agent_id=agent.agent_id,\n", ")\n", "\n", - "pprint(session_response)" + "pprint(session_response.turns)" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 24, "id": "f87a376d", "metadata": {}, "outputs": [ @@ -3571,7 +2414,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 25, "id": "a2b293bc", "metadata": {}, "outputs": [ @@ -3586,7 +2429,7 @@ "},\n", "{\n", "│ │ 'input_query': 'In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title. Search the web for the answer.',\n", - "│ │ 'generated_answer': 'Bill Cosby (BSM-471) first appears in the episode \"Trapper Keeper\" (Season 4, Episode 12) of South Park.',\n", + "│ │ 'generated_answer': 'Bill Cosby first appears in the episode \"Trapped in the Closet\" (Season 9, Episode 12) of South Park.',\n", "│ │ 'expected_answer': 'Season 4, Episode 12'\n", "},\n", "{\n", @@ -3606,7 +2449,7 @@ "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m: \u001b[32m'In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title. Search the web for the answer.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m'Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appears in the episode \"Trapper Keeper\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 4, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.'\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m'Bill Cosby first appears in the episode \"Trapped in the Closet\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 9, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.'\u001b[0m,\n", "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m: \u001b[32m'Season 4, Episode 12'\u001b[0m\n", "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", @@ -3626,8 +2469,8 @@ "
ScoringScoreResponse(\n",
               "results={\n",
               "│   │   'basic::subset_of': ScoringResult(\n",
-              "│   │   │   aggregated_results={'accuracy': {'accuracy': 1.0, 'num_correct': 3.0, 'num_total': 3}},\n",
-              "│   │   │   score_rows=[{'score': 1.0}, {'score': 1.0}, {'score': 1.0}]\n",
+              "│   │   │   aggregated_results={'accuracy': {'accuracy': 0.6666666666666666, 'num_correct': 2.0, 'num_total': 3}},\n",
+              "│   │   │   score_rows=[{'score': 1.0}, {'score': 0.0}, {'score': 1.0}]\n",
               "│   │   )\n",
               "}\n",
               ")\n",
@@ -3637,8 +2480,8 @@
               "\u001b[1;35mScoringScoreResponse\u001b[0m\u001b[1m(\u001b[0m\n",
               "\u001b[2;32m│   \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m{\u001b[0m\n",
               "\u001b[2;32m│   │   \u001b[0m\u001b[32m'basic::subset_of'\u001b[0m: \u001b[1;35mScoringResult\u001b[0m\u001b[1m(\u001b[0m\n",
-              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m3.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n",
-              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n",
+              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m0.6666666666666666\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m2.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n",
+              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n",
               "\u001b[2;32m│   │   \u001b[0m\u001b[1m)\u001b[0m\n",
               "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
               "\u001b[1m)\u001b[0m\n"
@@ -3691,7 +2534,7 @@
     },
     {
       "cell_type": "code",
-      "execution_count": 19,
+      "execution_count": 26,
       "id": "agkWgToGAsuA",
       "metadata": {
         "colab": {
@@ -3706,7 +2549,8 @@
           "name": "stdout",
           "output_type": "stream",
           "text": [
-            "Getting traces for session_id=72993b3e-6030-44f5-9f48-664449d2b6d3\n"
+            "Getting traces for session_id=d73d9aaa-65ac-4255-8153-9f5cbff6e01e\n",
+            "Here are examples of traces:\n"
           ]
         },
         {
@@ -3714,88 +2558,12 @@
             "text/html": [
               "
[\n",
               "{\n",
-              "│   │   'input': [\n",
-              "│   │   │   '{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}'\n",
-              "│   │   ],\n",
-              "│   │   'output': \"content:  tool_calls: [ToolCall(call_id='8b7294ec-a83f-4798-ad8f-6bed662f08b6', tool_name=<BuiltinTool.brave_search: 'brave_search'>, arguments={'query': 'NBA Western Conference Finals 2024 teams'})]\"\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"}}]}',\n",
-              "│   │   'output': '{\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (635) TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (208) AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (178) WS: Derrick White (2.9) More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': [\n",
-              "│   │   │   '{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (635) TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (208) AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (178) WS: Derrick White (2.9) More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-              "│   │   ],\n",
-              "│   │   'output': 'content: The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves. tool_calls: []'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': [\n",
-              "│   │   │   '{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (635) TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (208) AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (178) WS: Derrick White (2.9) More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null}]}\"}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}'\n",
-              "│   │   ],\n",
-              "│   │   'output': \"content:  tool_calls: [ToolCall(call_id='fc0441bf-05ad-48d0-8034-4e19cb835904', tool_name=<BuiltinTool.brave_search: 'brave_search'>, arguments={'query': 'Bill Cosby South Park episode'})]\"\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}',\n",
-              "│   │   'output': '{\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': [\n",
-              "│   │   │   '{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (635) TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (208) AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (178) WS: Derrick White (2.9) More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null}]}\"}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-              "│   │   ],\n",
-              "│   │   'output': 'content: Bill Cosby (BSM-471) first appears in the episode \"Trapper Keeper\" (Season 4, Episode 12) of South Park. tool_calls: []'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': [\n",
-              "│   │   │   '{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (635) TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (208) AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (178) WS: Derrick White (2.9) More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null}]}\"}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}]}\"}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"Bill Cosby (BSM-471) first appears in the episode \\\\\"Trapper Keeper\\\\\" (Season 4, Episode 12) of South Park.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null}'\n",
-              "│   │   ],\n",
-              "│   │   'output': \"content:  tool_calls: [ToolCall(call_id='79276f65-3600-489d-ab41-d5a71dcaf075', tool_name=<BuiltinTool.brave_search: 'brave_search'>, arguments={'query': 'Andrew Tate kickboxing name'})]\"\n",
+              "│   │   'input': '[{\"role\": \"system\", \"content\": \"You are a helpful assistant. Use web_search tool to answer the questions.\"}, {\"role\": \"user\", \"content\": \"Which teams played in the NBA western conference finals of 2024. Search the web for the answer.\", \"context\": null}]',\n",
+              "│   │   'output': '{\"content\": \"\", \"tool_calls\": [{\"call_id\": \"5f77ab69-72d9-4d51-b96c-bd4352ced54a\", \"tool_name\": \"brave_search\", \"arguments\": {\"query\": \"NBA Western Conference Finals 2024 teams\"}, \"arguments_json\": \"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"}\"}]}'\n",
               "},\n",
               "{\n",
-              "│   │   'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Andrew Tate kickboxing name\"}}]}',\n",
-              "│   │   'output': '{\"role\":\"tool\",\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Andrew Tate kickboxing name\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\\\\\", \\\\\"url\\\\\": \\\\\"https://biographywallah.com/andrew-tate-biography/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\\\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old (as of 2024)NationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\\\\\", \\\\\"score\\\\\": 0.80698997, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\\\\\", \\\\\"url\\\\\": \\\\\"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\\\\\u2019s life has been full of adventure.\\\\\", \\\\\"score\\\\\": 0.78194773, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate (\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\") | MMA Fighter Page - Tapology\\\\\", \\\\\"url\\\\\": \\\\\"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate (\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\") | MMA Fighter Page | Tapology Andrew \\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\" Tate Andrew Tate Name: Andrew Tate Height: 6\\'1\\\\\\\\\\\\\" (185cm) | Reach: Andrew Tate is ineligible for Tapology\\'s regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\\\\\\\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\\\\\", \\\\\"score\\\\\": 0.6999322, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"About Andrew Tate: A Journey from Champion to Controversy\\\\\", \\\\\"url\\\\\": \\\\\"https://reachmorpheus.com/andrew-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s kickboxing career, beginning in 2005, is a tale of determination and skill. He quickly made a name for himself in the sport, rising through the ranks with his unique fighting style and strategic approach, honed by his chess-playing background.\\\\\", \\\\\"score\\\\\": 0.6490677, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact\\\\\", \\\\\"url\\\\\": \\\\\"https://www.mmafullcontact.com/andrew-tate-kickboxing/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\\\\\\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\\\\\\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\\\\\\\u2019s upcoming match and Tate\\\\\\\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\\\\\", \\\\\"score\\\\\": 0.53050464, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input': [\n",
-              "│   │   │   '{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown (20.8 / 5.4 / 5.0) 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (635) TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (208) AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 (178) WS: Derrick White (2.9) More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null}]}\"}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses (TV Episode 1998) - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}]}\"}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"Bill Cosby (BSM-471) first appears in the episode \\\\\"Trapper Keeper\\\\\" (Season 4, Episode 12) of South Park.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}',\n",
-              "│   │   │   '{\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null}',\n",
-              "│   │   │   '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Andrew Tate kickboxing name\"}}]}',\n",
-              "│   │   │   '{\"role\":\"tool\",\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Andrew Tate kickboxing name\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\\\\\", \\\\\"url\\\\\": \\\\\"https://biographywallah.com/andrew-tate-biography/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\\\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old (as of 2024)NationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\\\\\", \\\\\"score\\\\\": 0.80698997, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\\\\\", \\\\\"url\\\\\": \\\\\"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\\\\\u2019s life has been full of adventure.\\\\\", \\\\\"score\\\\\": 0.78194773, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate (\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\") | MMA Fighter Page - Tapology\\\\\", \\\\\"url\\\\\": \\\\\"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate (\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\") | MMA Fighter Page | Tapology Andrew \\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\" Tate Andrew Tate Name: Andrew Tate Height: 6\\'1\\\\\\\\\\\\\" (185cm) | Reach: Andrew Tate is ineligible for Tapology\\'s regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\\\\\\\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\\\\\", \\\\\"score\\\\\": 0.6999322, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"About Andrew Tate: A Journey from Champion to Controversy\\\\\", \\\\\"url\\\\\": \\\\\"https://reachmorpheus.com/andrew-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s kickboxing career, beginning in 2005, is a tale of determination and skill. He quickly made a name for himself in the sport, rising through the ranks with his unique fighting style and strategic approach, honed by his chess-playing background.\\\\\", \\\\\"score\\\\\": 0.6490677, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact\\\\\", \\\\\"url\\\\\": \\\\\"https://www.mmafullcontact.com/andrew-tate-kickboxing/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\\\\\\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\\\\\\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\\\\\\\u2019s upcoming match and Tate\\\\\\\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\\\\\", \\\\\"score\\\\\": 0.53050464, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-              "│   │   ],\n",
-              "│   │   'output': 'content: Andrew Tate\\'s kickboxing name is \"King Cobra.\" tool_calls: []'\n",
+              "│   │   'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"},\"arguments_json\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"}\"}]}',\n",
+              "│   │   'output': '{\"role\":\"tool\",\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7   Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\\\\\\\u00a0Reference\\\\\\\\u202f\\\\\\\\u00ae Baseball Football (college) Basketball (college) Hockey F\\\\\\\\u00fatbol Blog Stathead\\\\\\\\u202f\\\\\\\\u00ae Immaculate Grid\\\\\\\\u202f\\\\\\\\u00ae\\\\\", \\\\\"score\\\\\": 0.89030397, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/standings\\\\\", \\\\\"content\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\\\\\\\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children\\'s Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries (\\'PENN\\').\\\\\", \\\\\"score\\\\\": 0.83549726, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) | NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: \\'This is special, coming from the West\\' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\\\\\", \\\\\"score\\\\\": 0.75312227, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024?os=wtmbloozowcj&ref=app\\\\\", \\\\\"content\\\\\": \\\\\"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 (Ep. 25) Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston\\'s NBA-record 18th championship. WE DID ITTTT!\\' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\\\\\", \\\\\"score\\\\\": 0.63234437, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2025 NBA Playoffs: Standings, bracket and clinching updates\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\\\\\", \\\\\"content\\\\\": \\\\\"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\\\\\\\\\\\"Access Content\\\\\\\\\\\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\\\\\", \\\\\"score\\\\\": 0.13435538, \\\\\"raw_content\\\\\": null}]}\"}'\n",
               "}\n",
               "]\n",
               "
\n" @@ -3803,88 +2571,12 @@ "text/plain": [ "\u001b[1m[\u001b[0m\n", "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m\"content: tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32mToolCall\u001b[0m\u001b[32m(\u001b[0m\u001b[32mcall_id\u001b[0m\u001b[32m='8b7294ec-a83f-4798-ad8f-6bed662f08b6', \u001b[0m\u001b[32mtool_name\u001b[0m\u001b[32m=\u001b[0m\u001b[32m<\u001b[0m\u001b[32mBuiltinTool.brave_search:\u001b[0m\u001b[32m 'brave_search'>, \u001b[0m\u001b[32marguments\u001b[0m\u001b[32m=\u001b[0m\u001b[32m{\u001b[0m\u001b[32m'query': 'NBA Western Conference Finals 2024 teams'\u001b[0m\u001b[32m}\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\"\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown \u001b[0m\u001b[32m(\u001b[0m\u001b[32m20.8 / 5.4 / 5.0\u001b[0m\u001b[32m)\u001b[0m\u001b[32m 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m635\u001b[0m\u001b[32m)\u001b[0m\u001b[32m TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m208\u001b[0m\u001b[32m)\u001b[0m\u001b[32m AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m178\u001b[0m\u001b[32m)\u001b[0m\u001b[32m WS: Derrick White \u001b[0m\u001b[32m(\u001b[0m\u001b[32m2.9\u001b[0m\u001b[32m)\u001b[0m\u001b[32m More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;39m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown \u001b[0m\u001b[32m(\u001b[0m\u001b[32m20.8 / 5.4 / 5.0\u001b[0m\u001b[32m)\u001b[0m\u001b[32m 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m635\u001b[0m\u001b[32m)\u001b[0m\u001b[32m TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m208\u001b[0m\u001b[32m)\u001b[0m\u001b[32m AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m178\u001b[0m\u001b[32m)\u001b[0m\u001b[32m WS: Derrick White \u001b[0m\u001b[32m(\u001b[0m\u001b[32m2.9\u001b[0m\u001b[32m)\u001b[0m\u001b[32m More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'content: The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves. tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;39m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown \u001b[0m\u001b[32m(\u001b[0m\u001b[32m20.8 / 5.4 / 5.0\u001b[0m\u001b[32m)\u001b[0m\u001b[32m 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m635\u001b[0m\u001b[32m)\u001b[0m\u001b[32m TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m208\u001b[0m\u001b[32m)\u001b[0m\u001b[32m AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m178\u001b[0m\u001b[32m)\u001b[0m\u001b[32m WS: Derrick White \u001b[0m\u001b[32m(\u001b[0m\u001b[32m2.9\u001b[0m\u001b[32m)\u001b[0m\u001b[32m More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title.\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m\"content: tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32mToolCall\u001b[0m\u001b[32m(\u001b[0m\u001b[32mcall_id\u001b[0m\u001b[32m='fc0441bf-05ad-48d0-8034-4e19cb835904', \u001b[0m\u001b[32mtool_name\u001b[0m\u001b[32m=, \u001b[0m\u001b[32marguments\u001b[0m\u001b[32m=\u001b[0m\u001b[32m{\u001b[0m\u001b[32m'query': 'Bill Cosby South Park episode'\u001b[0m\u001b[32m}\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\"\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"Bill Cosby South Park episode\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Trapper Keeper \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth_Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m The main plot of the episode involving the Trapper Keeper was written before the election,\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m but the subplot is a parody of the controversy surrounding the election\\'s outcome.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m2\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m3\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;39m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown \u001b[0m\u001b[32m(\u001b[0m\u001b[32m20.8 / 5.4 / 5.0\u001b[0m\u001b[32m)\u001b[0m\u001b[32m 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m635\u001b[0m\u001b[32m)\u001b[0m\u001b[32m TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m208\u001b[0m\u001b[32m)\u001b[0m\u001b[32m AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m178\u001b[0m\u001b[32m)\u001b[0m\u001b[32m WS: Derrick White \u001b[0m\u001b[32m(\u001b[0m\u001b[32m2.9\u001b[0m\u001b[32m)\u001b[0m\u001b[32m More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title.\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"Bill Cosby South Park episode\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Trapper Keeper \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth_Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m The main plot of the episode involving the Trapper Keeper was written before the election,\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m but the subplot is a parody of the controversy surrounding the election\\'s outcome.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m2\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m3\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'content: Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appears in the episode \"Trapper Keeper\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 4, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park. tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m\u001b[39m: \u001b[0m\u001b[1;39m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown \u001b[0m\u001b[32m(\u001b[0m\u001b[32m20.8 / 5.4 / 5.0\u001b[0m\u001b[32m)\u001b[0m\u001b[32m 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m635\u001b[0m\u001b[32m)\u001b[0m\u001b[32m TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m208\u001b[0m\u001b[32m)\u001b[0m\u001b[32m AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m178\u001b[0m\u001b[32m)\u001b[0m\u001b[32m WS: Derrick White \u001b[0m\u001b[32m(\u001b[0m\u001b[32m2.9\u001b[0m\u001b[32m)\u001b[0m\u001b[32m More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title.\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"Bill Cosby South Park episode\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Trapper Keeper \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth_Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m The main plot of the episode involving the Trapper Keeper was written before the election,\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m but the subplot is a parody of the controversy surrounding the election\\'s outcome.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m2\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m3\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appears in the episode \\\\\"Trapper Keeper\\\\\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 4, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m\"content: tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32mToolCall\u001b[0m\u001b[32m(\u001b[0m\u001b[32mcall_id\u001b[0m\u001b[32m='79276f65-3600-489d-ab41-d5a71dcaf075', \u001b[0m\u001b[32mtool_name\u001b[0m\u001b[32m=\u001b[0m\u001b[32m, \u001b[0m\u001b[32marguments\u001b[0m\u001b[32m=\u001b[0m\u001b[32m{\u001b[0m\u001b[32m'query': 'Andrew Tate kickboxing name'\u001b[0m\u001b[32m}\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\"\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\": \"system\", \"content\": \"You are a helpful assistant. Use web_search tool to answer the questions.\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\": \"user\", \"content\": \"Which teams played in the NBA western conference finals of 2024. Search the web for the answer.\", \"context\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"content\": \"\", \"tool_calls\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\": \"5f77ab69-72d9-4d51-b96c-bd4352ced54a\", \"tool_name\": \"brave_search\", \"arguments\": \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\": \"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \"arguments_json\": \"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"Andrew Tate kickboxing name\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"Andrew Tate kickboxing name\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\\\\\", \\\\\"url\\\\\": \\\\\"https://biographywallah.com/andrew-tate-biography/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\\\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old \u001b[0m\u001b[32m(\u001b[0m\u001b[32mas of 2024\u001b[0m\u001b[32m)\u001b[0m\u001b[32mNationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\\\\\", \\\\\"score\\\\\": 0.80698997, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"The Life Of Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBy Andrew Tate Himself ... - Sidekick Boxing\\\\\", \\\\\"url\\\\\": \\\\\"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\\\\\u2019s life has been full of adventure.\\\\\", \\\\\"score\\\\\": 0.78194773, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\"\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | MMA Fighter Page - Tapology\\\\\", \\\\\"url\\\\\": \\\\\"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\"\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | MMA Fighter Page | Tapology Andrew \\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\" Tate Andrew Tate Name: Andrew Tate Height: 6\\'1\\\\\\\\\\\\\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32m185cm\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | Reach: Andrew Tate is ineligible for Tapology\\'s regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\\\\\\\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\\\\\", \\\\\"score\\\\\": 0.6999322, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"About Andrew Tate: A Journey from Champion to Controversy\\\\\", \\\\\"url\\\\\": \\\\\"https://reachmorpheus.com/andrew-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s kickboxing career, beginning in 2005, is a tale of determination and skill. He quickly made a name for himself in the sport, rising through the ranks with his unique fighting style and strategic approach, honed by his chess-playing background.\\\\\", \\\\\"score\\\\\": 0.6490677, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact\\\\\", \\\\\"url\\\\\": \\\\\"https://www.mmafullcontact.com/andrew-tate-kickboxing/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\\\\\\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\\\\\\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\\\\\\\u2019s upcoming match and Tate\\\\\\\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\\\\\", \\\\\"score\\\\\": 0.53050464, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"8b7294ec-a83f-4798-ad8f-6bed662f08b6\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Western Conference Finals Mavericks vs. Timberwolves League Champion: Boston Celtics. Finals MVP: Jaylen Brown \u001b[0m\u001b[32m(\u001b[0m\u001b[32m20.8 / 5.4 / 5.0\u001b[0m\u001b[32m)\u001b[0m\u001b[32m 2024 Playoff Leaders: PTS: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m635\u001b[0m\u001b[32m)\u001b[0m\u001b[32m TRB: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m208\u001b[0m\u001b[32m)\u001b[0m\u001b[32m AST: Luka Don\\\\\\\\u010di\\\\\\\\u0107 \u001b[0m\u001b[32m(\u001b[0m\u001b[32m178\u001b[0m\u001b[32m)\u001b[0m\u001b[32m WS: Derrick White \u001b[0m\u001b[32m(\u001b[0m\u001b[32m2.9\u001b[0m\u001b[32m)\u001b[0m\u001b[32m More playoffs info\\\\\", \\\\\"score\\\\\": 0.9310187, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates, schedule and more - Sportskeeda\\\\\", \\\\\"url\\\\\": \\\\\"https://www.sportskeeda.com/basketball/news-nba-western-conference-finals-2024-dates-schedule-and-more\\\\\", \\\\\"content\\\\\": \\\\\"NBA Western Conference Finals 2024: Dates & Schedule The 2023-24 NBA Western Conference Finals will start on Wednesday, May 22. The Mavericks will face the team that wins in Game 7 between the\\\\\", \\\\\"score\\\\\": 0.8914433, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"The Dallas Mavericks and Minnesota Timberwolves have advanced to the 2024 Western Conference Finals during the NBA playoffs.\\\\\", \\\\\"score\\\\\": 0.8884594, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference playoff bracket - Basketnews.com\\\\\", \\\\\"url\\\\\": \\\\\"https://basketnews.com/news-204687-2024-nba-western-conference-playoff-bracket.html\\\\\", \\\\\"content\\\\\": \\\\\"In the 2024 NBA Western Conference playoffs, the Oklahoma City Thunder clinched the No. 1 seed. Every team from the Western Conference played their final game of the regular season, and two playoff pairs have been confirmed. The Los Angeles Lakers beat the New Orleans Pelicans, 110-106, in the Play-In Tournament to secure the 7th seed to set up a first-round matchup with the Denver Nuggets. Meanwhile, the Sacramento Kings will host the Golden State Warriors in the second Western Conference NBA Play-In Tournament game. The winners secure the No. 8 seed in the NBA playoffs for its conference. EuroLeague Play-In: Baskonia-Virtus game schedule announced\\\\\", \\\\\"score\\\\\": 0.8479807, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Finals 2024 - Celtics-Mavericks news, schedule, scores and ... - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/story/_/id/39943302/nba-playoffs-2024-conference-finals-news-scores-highlights\\\\\", \\\\\"content\\\\\": \\\\\"The Boston Celtics are the 2024 NBA Champions. ... Western Conference. Final 2023-24 NBA regular-season standings. Which team left standing has the most trips to the NBA Finals? Here is a look at\\\\\", \\\\\"score\\\\\": 0.81979275, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title.\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"Bill Cosby South Park episode\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"fc0441bf-05ad-48d0-8034-4e19cb835904\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mandroid\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - IMDb\\\\\", \\\\\"url\\\\\": \\\\\"https://www.imdb.com/title/tt0705915/characters/nm0005295\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"South Park\\\\\\\\\\\\\" Clubhouses \u001b[0m\u001b[32m(\u001b[0m\u001b[32mTV Episode 1998\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Trey Parker as Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 - IMDb Awards & Events Trey Parker: Stan Marsh, Eric Cartman, Phillip, Randy Marsh, Fat Abbot, Mr. Garrison, Mr. Mackey, 3rd Fat Abbot character, Roy, Teenage Boy #1, Clyde, Bill Cosby, Teenage Boy #2 Mr. Garrison : Stan, are you paying attention? Stan : Yes, Mr. Garrison. Stan Marsh : Dare. Stan Marsh : What? Release Dates | Official Sites | Company Credits | Filming & Production | Technical Specs Photo & Video User Lists Related lists from IMDb users 2024 Watched TV Shows\\\\\", \\\\\"score\\\\\": 0.4604593, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Trapper Keeper \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mSouth_Park\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m The main plot of the episode involving the Trapper Keeper was written before the election,\u001b[0m\u001b[32m[\u001b[0m\u001b[32m1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m but the subplot is a parody of the controversy surrounding the election\\'s outcome.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m2\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.\u001b[0m\u001b[32m[\u001b[0m\u001b[32m3\u001b[0m\u001b[32m]\u001b[0m\u001b[32m \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appears in the episode \\\\\"Trapper Keeper\\\\\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 4, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"Andrew Tate kickboxing name\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"79276f65-3600-489d-ab41-d5a71dcaf075\",\"tool_name\":\"brave_search\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"Andrew Tate kickboxing name\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\\\\\", \\\\\"url\\\\\": \\\\\"https://biographywallah.com/andrew-tate-biography/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\\\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old \u001b[0m\u001b[32m(\u001b[0m\u001b[32mas of 2024\u001b[0m\u001b[32m)\u001b[0m\u001b[32mNationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\\\\\", \\\\\"score\\\\\": 0.80698997, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"The Life Of Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBy Andrew Tate Himself ... - Sidekick Boxing\\\\\", \\\\\"url\\\\\": \\\\\"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\\\\\u2019s life has been full of adventure.\\\\\", \\\\\"score\\\\\": 0.78194773, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\"\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | MMA Fighter Page - Tapology\\\\\", \\\\\"url\\\\\": \\\\\"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\"\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | MMA Fighter Page | Tapology Andrew \\\\\\\\\\\\\"King Cobra\\\\\\\\\\\\\" Tate Andrew Tate Name: Andrew Tate Height: 6\\'1\\\\\\\\\\\\\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32m185cm\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | Reach: Andrew Tate is ineligible for Tapology\\'s regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\\\\\\\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\\\\\", \\\\\"score\\\\\": 0.6999322, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"About Andrew Tate: A Journey from Champion to Controversy\\\\\", \\\\\"url\\\\\": \\\\\"https://reachmorpheus.com/andrew-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s kickboxing career, beginning in 2005, is a tale of determination and skill. He quickly made a name for himself in the sport, rising through the ranks with his unique fighting style and strategic approach, honed by his chess-playing background.\\\\\", \\\\\"score\\\\\": 0.6490677, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact\\\\\", \\\\\"url\\\\\": \\\\\"https://www.mmafullcontact.com/andrew-tate-kickboxing/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate\\'s Kickboxing Career & Biography - MMA Full Contact Andrew Tate\\\\\\\\u2019s Kickboxing Career & Biography 2 Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career 4 Will Andrew Tate fight KSI? Notable Opponents and Fights in Andrew Tate\\\\\\\\u2019s Kickboxing Career Will Andrew Tate fight KSI? Similarly, Andrew Tate, known for his successful kickboxing career, has also shown interest in a potential fight with KSI. In conclusion, while there\\\\\\\\u2019s been plenty of interest and discussion about a potential boxing match between KSI and Andrew Tate, no official confirmation has been made as of now. With KSI\\\\\\\\u2019s upcoming match and Tate\\\\\\\\u2019s current personal circumstances, fans and followers of both personalities will have to wait for more updates on this potential fight.\\\\\", \\\\\"score\\\\\": 0.53050464, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m'content: Andrew Tate\\'s kickboxing name is \"King Cobra.\" tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m,\"arguments_json\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m4-1\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\\\\\\\u00a0Reference\\\\\\\\u202f\\\\\\\\u00ae Baseball Football \u001b[0m\u001b[32m(\u001b[0m\u001b[32mcollege\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Basketball \u001b[0m\u001b[32m(\u001b[0m\u001b[32mcollege\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Hockey F\\\\\\\\u00fatbol Blog Stathead\\\\\\\\u202f\\\\\\\\u00ae Immaculate Grid\\\\\\\\u202f\\\\\\\\u00ae\\\\\", \\\\\"score\\\\\": 0.89030397, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/standings\\\\\", \\\\\"content\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\\\\\\\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children\\'s Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\'PENN\\'\u001b[0m\u001b[32m)\u001b[0m\u001b[32m.\\\\\", \\\\\"score\\\\\": 0.83549726, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: \\'This is special, coming from the West\\' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\\\\\", \\\\\"score\\\\\": 0.75312227, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024?\u001b[0m\u001b[32mos\u001b[0m\u001b[32m=\u001b[0m\u001b[32mwtmbloozowcj\u001b[0m\u001b[32m&\u001b[0m\u001b[32mref\u001b[0m\u001b[32m=\u001b[0m\u001b[32mapp\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 \u001b[0m\u001b[32m(\u001b[0m\u001b[32mEp. 25\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston\\'s NBA-record 18th championship. WE DID ITTTT!\\' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\\\\\", \\\\\"score\\\\\": 0.63234437, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2025 NBA Playoffs: Standings, bracket and clinching updates\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\\\\\", \\\\\"content\\\\\": \\\\\"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\\\\\\\\\\\"Access Content\\\\\\\\\\\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\\\\\", \\\\\"score\\\\\": 0.13435538, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", "\u001b[1m]\u001b[0m\n" ] @@ -3911,7 +2603,8 @@ " if span.attributes[\"output\"] != \"no shields\":\n", " agent_logs.append(span.attributes)\n", "\n", - "pprint(agent_logs)\n" + "print(\"Here are examples of traces:\")\n", + "pprint(agent_logs[:2])\n" ] }, { @@ -3927,7 +2620,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 27, "id": "sy4Xaff_Avuu", "metadata": { "colab": { @@ -3938,72 +2631,14 @@ "outputId": "1b14b5ed-4c77-47c4-edfb-1c13a88e5ef4" }, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'input': ['{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}', '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}'], 'output': 'content: Let me check the latest sports news. tool_calls: []'}\n", - "{'input': ['{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}', '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"Let me check the latest sports news.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}', '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}'], 'output': \"content: tool_calls: [ToolCall(call_id='26345b28-7f75-401e-88e3-77933cb70a2e', tool_name=, arguments={'query': 'Bill Cosby South Park episode'})]\"}\n", - "{'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}', 'output': '{\"role\":\"tool\",\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby | South Park Archives | Fandom\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.fandom.com/wiki/Bill_Cosby\\\\\", \\\\\"content\\\\\": \\\\\"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\\\\\", \\\\\"score\\\\\": 0.34707275, \\\\\"raw_content\\\\\": null}]}\"}'}\n", - "{'input': ['{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}', '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"Let me check the latest sports news.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}', '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}', '{\"role\":\"tool\",\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby | South Park Archives | Fandom\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.fandom.com/wiki/Bill_Cosby\\\\\", \\\\\"content\\\\\": \\\\\"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\\\\\", \\\\\"score\\\\\": 0.34707275, \\\\\"raw_content\\\\\": null}]}\"}'], 'output': 'content: Bill Cosby (BSM-471) first appears in the episode \"Trapper Keeper\" (Season 4, Episode 12) of South Park. tool_calls: []'}\n", - "{'input': ['{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}', '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"Let me check the latest sports news.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}', '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}', '{\"role\":\"tool\",\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby | South Park Archives | Fandom\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.fandom.com/wiki/Bill_Cosby\\\\\", \\\\\"content\\\\\": \\\\\"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\\\\\", \\\\\"score\\\\\": 0.34707275, \\\\\"raw_content\\\\\": null}]}\"}', '{\"role\":\"assistant\",\"content\":\"Bill Cosby (BSM-471) first appears in the episode \\\\\"Trapper Keeper\\\\\" (Season 4, Episode 12) of South Park.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}', '{\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null}'], 'output': \"content: tool_calls: [ToolCall(call_id='fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba', tool_name=, arguments={'query': 'Andrew Tate kickboxing name'})]\"}\n", - "{'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Andrew Tate kickboxing name\"}}]}', 'output': '{\"role\":\"tool\",\"call_id\":\"fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Andrew Tate kickboxing name\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"50 Facts About Andrew Tate - Facts.net\\\\\", \\\\\"url\\\\\": \\\\\"https://facts.net/andrew-tate-facts/\\\\\", \\\\\"content\\\\\": \\\\\"Full Name: Andrew Tate\\'s full name is Emory Andrew Tate III, named after his father, a celebrated chess player. Date of Birth: ... Kickboxing Start: Tate began his kickboxing career in 2005, starting his journey as a professional fighter, which would later be a significant part of his persona. First Championship:\\\\\", \\\\\"score\\\\\": 0.8967681, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\\\\\", \\\\\"url\\\\\": \\\\\"https://biographywallah.com/andrew-tate-biography/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\\\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old (as of 2024)NationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\\\\\", \\\\\"score\\\\\": 0.80698997, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\\\\\", \\\\\"url\\\\\": \\\\\"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\\\\\u2019s life has been full of adventure.\\\\\", \\\\\"score\\\\\": 0.7817479, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"50 Facts About Andrew Tate\\\\\", \\\\\"url\\\\\": \\\\\"https://facts.net/celebrity/50-facts-about-andrew-tate/\\\\\", \\\\\"content\\\\\": \\\\\"50 Facts About Andrew Tate - Facts.net Everything Else Facts Everything Else Facts 50 Facts About Andrew Tate Known for his kickboxing prowess, internet fame, and polarizing views, Tate\\'s life is a blend of high achievements and significant legal troubles. Andrew Tate, a kickboxing champion turned internet personality, faced controversy and legal issues, showcasing the complexities of fame and the impact of social media influence on personal reputation. Andrew Tate\\'s kickboxing career is one of his most notable achievements. Andrew Tate, a former professional kickboxer turned internet personality, has made waves online with his controversial opinions and business ventures. 20 Tristan Tate Facts A Deep Dive into the Life of a Controversial Figure 47 Facts About Larenz Tate More Facts\\\\\", \\\\\"score\\\\\": 0.61834323, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate Kickboxing Record: Legacy of King Cobra\\\\\", \\\\\"url\\\\\": \\\\\"https://stagbite.com/andrew-tate-kickboxing-record/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Kickboxing Record: Legacy Of King Cobra \\\\\\\\u2013 Stagbite Andrew Tate Kickboxing Record: Legacy of King Cobra Andrew Tate Kickboxing Record: Legacy of King Cobra Over the course of his career, Andrew Tate amassed an impressive kickboxing record of 76 wins and 9 losses, with 23 of those victories coming via knockout or technical knockout. Andrew Tate\\\\\\\\u2019s Kickboxing Record What is Andrew Tate\\\\\\\\u2019s kickboxing record? Andrew Tate has a kickboxing record of 76 wins and 9 losses, with 23 wins coming via knockout or technical knockout. What titles did Andrew Tate win during his kickboxing career? We talk, write, and share some of the best Internet stories on Entertainment, Culture, Travel, Food, Books along with the social media trends & viral bees.\\\\\", \\\\\"score\\\\\": 0.59796065, \\\\\"raw_content\\\\\": null}]}\"}'}\n", - "{'input': ['{\"role\":\"system\",\"content\":\"You are a helpful assistant. Use search tool to answer the questions. \"}', '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"Let me check the latest sports news.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}', '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Bill Cosby South Park episode\"}}]}', '{\"role\":\"tool\",\"call_id\":\"26345b28-7f75-401e-88e3-77933cb70a2e\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Bill Cosby South Park episode\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"Bill Cosby and Taylor Swift Duet - South Park Studios\\\\\", \\\\\"url\\\\\": \\\\\"https://www.southparkstudios.com/video-clips/90r7i1/south-park-bill-cosby-and-taylor-swift-duet\\\\\", \\\\\"content\\\\\": \\\\\"01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:03 Bill Cosby and Taylor Swift Duet South ParkS18 E10 ------------------------------------------------------- The holiday special continues with Bill Cosby and Taylor Swift\\'s rendition of \\\\\\\\\\\\\"It\\'s Snowing Out There\\\\\\\\\\\\\". 01:31 #WeBelieveInYou South ParkS18 E10 -------------------------------------- With everyone watching, Kyle takes the opportunity to reach out to his brother. 01:47 Watch Your Microaggressions, Bro South ParkS19 E1 ------------------------------------------------------ Cartman\\'s plan to frame PC Principal backfires. South ParkS19 E1 -------------------------------------- After hearing that the PC people have targeted Kyle, Cartman vows to help.\\\\\", \\\\\"score\\\\\": 0.685971, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby is Here to See You - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/video-clips/wfot8s/south-park-bill-cosby-is-here-to-see-you\\\\\", \\\\\"content\\\\\": \\\\\"01:56 It\\'s Not About Music South ParkS18 E9 ------------------------------------------ At home, Randy sees the consequences of Lorde\\'s performance and calls the Record Producer to try and fix it. 01:24 Lorde\\'s Hologram South ParkS18 E9 -------------------------------------- The Record Producer reveals the truth about the music industry... South ParkS18 E9 --------------------------------------------- Randy catches Sharon with Tupac\\'s hologram. 01:37 I\\'ve Got Your Son, Lorde South ParkS18 E10 ----------------------------------------------- The Record Producer takes Stan and Kyle hostage. 01:05 Bill Cosby is Here to See You South ParkS18 E10 ---------------------------------------------------- Bill Cosby recruits Kyle and his hashtag for the big Holiday Special. 01:21 Lorde Is My Dad South ParkS18 E10 -------------------------------------- After trying to confront Cartman Bra, Stan finally reveals the truth about his dad.\\\\\", \\\\\"score\\\\\": 0.6643884, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby (android) | South Park Character ... - South Park Studios US\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.cc.com/wiki/Bill_Cosby_(android)\\\\\", \\\\\"content\\\\\": \\\\\"Bill Cosby (android) | South Park Character / Location / User talk etc | Official South Park Studios Wiki Sent back in time to destroy Eric Cartman\\'s Dawson\\'s Creek Trapper Keeper before it manifests into an omnipotent supercomputer that can destroy all humanity, \\\\\\\\\\\\\"Bill Cosby\\\\\\\\\\\\\" is really VSM471, an android or cyborg of some kind engineered by \\'hoomans\\' in the distant future. He fails in his initial missions to infiltrate South Park Elementary\\'s 4th Grade class, destroy the Trapper Keeper or Cartman himself, but with Stan Marsh and Kyle Broflovski\\'s aid, he is able to succeed in preventing his dismal future, and painfully fades from existence. South Park and all related titles, logos and characters are trademarks of Comedy Partners.\\\\\", \\\\\"score\\\\\": 0.5052006, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Trapper Keeper (South Park) - Wikipedia\\\\\", \\\\\"url\\\\\": \\\\\"https://en.wikipedia.org/wiki/Trapper_Keeper_(South_Park)\\\\\", \\\\\"content\\\\\": \\\\\"\\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" is the twelfth episode of the fourth season of the animated television series South Park, and the 60th episode of the series overall. In the episode, a man from the future wants Cartman\\'s new Trapper Keeper, while Mr. Garrison\\'s kindergarten class holds an election for class president with confusing results. It is one of the many South Park episodes that parodies a current event.[1] The main plot of the episode involving the Trapper Keeper was written before the election,[1] but the subplot is a parody of the controversy surrounding the election\\'s outcome.[2] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" did not originally feature the election storyline, only a subplot about Ike attending his first day of kindergarten.[3] \\\\\\\\\\\\\"Trapper Keeper\\\\\\\\\\\\\" Full episode at South Park Studios\\\\\", \\\\\"score\\\\\": 0.3839421, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Bill Cosby | South Park Archives | Fandom\\\\\", \\\\\"url\\\\\": \\\\\"https://southpark.fandom.com/wiki/Bill_Cosby\\\\\", \\\\\"content\\\\\": \\\\\"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\\\\\", \\\\\"score\\\\\": 0.34707275, \\\\\"raw_content\\\\\": null}]}\"}', '{\"role\":\"assistant\",\"content\":\"Bill Cosby (BSM-471) first appears in the episode \\\\\"Trapper Keeper\\\\\" (Season 4, Episode 12) of South Park.\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[]}', '{\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null}', '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"Andrew Tate kickboxing name\"}}]}', '{\"role\":\"tool\",\"call_id\":\"fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba\",\"tool_name\":\"brave_search\",\"content\":\"{\\\\\"query\\\\\": \\\\\"Andrew Tate kickboxing name\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"50 Facts About Andrew Tate - Facts.net\\\\\", \\\\\"url\\\\\": \\\\\"https://facts.net/andrew-tate-facts/\\\\\", \\\\\"content\\\\\": \\\\\"Full Name: Andrew Tate\\'s full name is Emory Andrew Tate III, named after his father, a celebrated chess player. Date of Birth: ... Kickboxing Start: Tate began his kickboxing career in 2005, starting his journey as a professional fighter, which would later be a significant part of his persona. First Championship:\\\\\", \\\\\"score\\\\\": 0.8967681, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth\\\\\", \\\\\"url\\\\\": \\\\\"https://biographywallah.com/andrew-tate-biography/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth \\\\\\\\u00bb Biography Wallah Andrew Tate Age, Height, Weight, Family, Parents, Biography, Net Worth Andrew Tate Biography NameAndrew TateReal nameEmory Andrew Tate IIIProfession \\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0\\\\\\\\u00a0Kickboxer, Commentator and BusinessmanDate of birth14 December 1986BirthplaceWashington D.C., United StatesAndrew Tate Age37 years old (as of 2024)NationalityBritish-AmericanZodiac SignSagittariusGenderMaleSchoolLocal School in Washington D.C., United StatesGirlfriend/SpouseNaghel GeorgianaSexual OrientationStraightNet worth$1000 Million Who is Andrew Tate? Andrew Tate is a British-American former professional kickboxing world champion businessman and media personality, who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate Age Andrew Tate was born on 1 December 1986 and is 37 years old. Andrew Tate\\\\\\\\u2019s Net Worth What is the net worth of Andrew Tate? Where is Andrew Tate from? How old is Andrew Tate?\\\\\", \\\\\"score\\\\\": 0.80698997, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\\\\\", \\\\\"url\\\\\": \\\\\"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\\\\\\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\\\\\\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\\\\\\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\\\\\\\u2019s life has been full of adventure.\\\\\", \\\\\"score\\\\\": 0.7817479, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"50 Facts About Andrew Tate\\\\\", \\\\\"url\\\\\": \\\\\"https://facts.net/celebrity/50-facts-about-andrew-tate/\\\\\", \\\\\"content\\\\\": \\\\\"50 Facts About Andrew Tate - Facts.net Everything Else Facts Everything Else Facts 50 Facts About Andrew Tate Known for his kickboxing prowess, internet fame, and polarizing views, Tate\\'s life is a blend of high achievements and significant legal troubles. Andrew Tate, a kickboxing champion turned internet personality, faced controversy and legal issues, showcasing the complexities of fame and the impact of social media influence on personal reputation. Andrew Tate\\'s kickboxing career is one of his most notable achievements. Andrew Tate, a former professional kickboxer turned internet personality, has made waves online with his controversial opinions and business ventures. 20 Tristan Tate Facts A Deep Dive into the Life of a Controversial Figure 47 Facts About Larenz Tate More Facts\\\\\", \\\\\"score\\\\\": 0.61834323, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"Andrew Tate Kickboxing Record: Legacy of King Cobra\\\\\", \\\\\"url\\\\\": \\\\\"https://stagbite.com/andrew-tate-kickboxing-record/\\\\\", \\\\\"content\\\\\": \\\\\"Andrew Tate Kickboxing Record: Legacy Of King Cobra \\\\\\\\u2013 Stagbite Andrew Tate Kickboxing Record: Legacy of King Cobra Andrew Tate Kickboxing Record: Legacy of King Cobra Over the course of his career, Andrew Tate amassed an impressive kickboxing record of 76 wins and 9 losses, with 23 of those victories coming via knockout or technical knockout. Andrew Tate\\\\\\\\u2019s Kickboxing Record What is Andrew Tate\\\\\\\\u2019s kickboxing record? Andrew Tate has a kickboxing record of 76 wins and 9 losses, with 23 wins coming via knockout or technical knockout. What titles did Andrew Tate win during his kickboxing career? We talk, write, and share some of the best Internet stories on Entertainment, Culture, Travel, Food, Books along with the social media trends & viral bees.\\\\\", \\\\\"score\\\\\": 0.59796065, \\\\\"raw_content\\\\\": null}]}\"}'], 'output': 'content: Andrew Tate\\'s kickboxing name is \"King Cobra.\" tool_calls: []'}\n" - ] - }, - { - "data": { - "text/html": [ - "
[\n",
-              "{\n",
-              "│   │   'input_query': '{\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null}',\n",
-              "│   │   'generated_answer': 'content: Let me check the latest sports news. tool_calls: []',\n",
-              "│   │   'expected_answer': 'brave_search'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input_query': '{\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title.\",\"context\":null}',\n",
-              "│   │   'generated_answer': \"content:  tool_calls: [ToolCall(call_id='26345b28-7f75-401e-88e3-77933cb70a2e', tool_name=<BuiltinTool.brave_search: 'brave_search'>, arguments={'query': 'Bill Cosby South Park episode'})]\",\n",
-              "│   │   'expected_answer': 'brave_search'\n",
-              "},\n",
-              "{\n",
-              "│   │   'input_query': '{\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null}',\n",
-              "│   │   'generated_answer': \"content:  tool_calls: [ToolCall(call_id='fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba', tool_name=<BuiltinTool.brave_search: 'brave_search'>, arguments={'query': 'Andrew Tate kickboxing name'})]\",\n",
-              "│   │   'expected_answer': 'brave_search'\n",
-              "}\n",
-              "]\n",
-              "
\n" - ], - "text/plain": [ - "\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"Which teams played in the NBA western conference finals of 2024\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m'content: Let me check the latest sports news. tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m: \u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title.\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m\"content: tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32mToolCall\u001b[0m\u001b[32m(\u001b[0m\u001b[32mcall_id\u001b[0m\u001b[32m='26345b28-7f75-401e-88e3-77933cb70a2e', \u001b[0m\u001b[32mtool_name\u001b[0m\u001b[32m=\u001b[0m\u001b[32m<\u001b[0m\u001b[32mBuiltinTool.brave_search:\u001b[0m\u001b[32m 'brave_search'>, \u001b[0m\u001b[32marguments\u001b[0m\u001b[32m=\u001b[0m\u001b[32m{\u001b[0m\u001b[32m'query': 'Bill Cosby South Park episode'\u001b[0m\u001b[32m}\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\"\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;39m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"user\",\"content\":\"What is the British-American kickboxer Andrew Tate\\'s kickboxing name?\",\"context\":null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\u001b[39m,\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m\"content: tool_calls: \u001b[0m\u001b[32m[\u001b[0m\u001b[32mToolCall\u001b[0m\u001b[32m(\u001b[0m\u001b[32mcall_id\u001b[0m\u001b[32m='fd4cc3c6-49d0-42e4-b0af-877e72f8d6ba', \u001b[0m\u001b[32mtool_name\u001b[0m\u001b[32m=\u001b[0m\u001b[32m, \u001b[0m\u001b[32marguments\u001b[0m\u001b[32m=\u001b[0m\u001b[32m{\u001b[0m\u001b[32m'query': 'Andrew Tate kickboxing name'\u001b[0m\u001b[32m}\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\"\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m: \u001b[32m'brave_search'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[1m]\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "data": { "text/html": [ "
ScoringScoreResponse(\n",
               "results={\n",
               "│   │   'basic::subset_of': ScoringResult(\n",
-              "│   │   │   aggregated_results={'accuracy': {'accuracy': 0.6666666666666666, 'num_correct': 2.0, 'num_total': 3}},\n",
-              "│   │   │   score_rows=[{'score': 0.0}, {'score': 1.0}, {'score': 1.0}]\n",
+              "│   │   │   aggregated_results={'accuracy': {'accuracy': 1.0, 'num_correct': 3.0, 'num_total': 3}},\n",
+              "│   │   │   score_rows=[{'score': 1.0}, {'score': 1.0}, {'score': 1.0}]\n",
               "│   │   )\n",
               "}\n",
               ")\n",
@@ -4013,8 +2648,8 @@
               "\u001b[1;35mScoringScoreResponse\u001b[0m\u001b[1m(\u001b[0m\n",
               "\u001b[2;32m│   \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m{\u001b[0m\n",
               "\u001b[2;32m│   │   \u001b[0m\u001b[32m'basic::subset_of'\u001b[0m: \u001b[1;35mScoringResult\u001b[0m\u001b[1m(\u001b[0m\n",
-              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m0.6666666666666666\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m2.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n",
-              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n",
+              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m3.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n",
+              "\u001b[2;32m│   │   │   \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n",
               "\u001b[2;32m│   │   \u001b[0m\u001b[1m)\u001b[0m\n",
               "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
               "\u001b[1m)\u001b[0m\n"
@@ -4034,19 +2669,20 @@
         "eval_rows = []\n",
         "\n",
         "for log in agent_logs:\n",
-        "    print(log)\n",
-        "    last_msg = log[\"input\"][-1]\n",
-        "    if '\"role\":\"user\"' in last_msg:\n",
+        "    input = json.loads(log[\"input\"])\n",
+        "    if isinstance(input, list):\n",
+        "        input = input[-1]\n",
+        "    if input[\"role\"] == \"user\":\n",
         "        eval_rows.append(\n",
         "            {\n",
-        "                \"input_query\": last_msg,\n",
-        "                \"generated_answer\": log[\"output\"],\n",
+        "                \"input_query\": input[\"content\"],\n",
+        "                \"generated_answer\":  log[\"output\"],\n",
         "                # check if generated_answer uses tools brave_search\n",
         "                \"expected_answer\": \"brave_search\",\n",
         "            },\n",
         "        )\n",
         "\n",
-        "pprint(eval_rows)\n",
+        "# pprint(eval_rows)\n",
         "scoring_params = {\n",
         "    \"basic::subset_of\": None,\n",
         "}\n",
@@ -4071,7 +2707,7 @@
     },
     {
       "cell_type": "code",
-      "execution_count": null,
+      "execution_count": 28,
       "id": "xG4Y84VQBb0g",
       "metadata": {
         "colab": {
@@ -4092,7 +2728,7 @@
               "│   │   │   score_rows=[\n",
               "│   │   │   │   {\n",
               "│   │   │   │   │   'score': 'B',\n",
-              "│   │   │   │   │   'judge_feedback': 'Answer: B, Explanation: The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it. The EXPECTED_RESPONSE only mentions \"LoRA\", which is present in all the points of the GENERATED_RESPONSE. The GENERATED_RESPONSE provides more details and specific topics related to LoRA, but it does not contradict the EXPECTED_RESPONSE.'\n",
+              "│   │   │   │   │   'judge_feedback': 'Answer: B, Explanation: The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it. The EXPECTED_RESPONSE only mentions \"LoRA\", which is a topic that is extensively covered in the GENERATED_RESPONSE. The GENERATED_RESPONSE provides more specific and detailed topics related to LoRA, but it does not contradict the EXPECTED_RESPONSE.'\n",
               "│   │   │   │   }\n",
               "│   │   │   ]\n",
               "│   │   ),\n",
@@ -4112,7 +2748,7 @@
               "\u001b[2;32m│   │   │   \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\n",
               "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1m{\u001b[0m\n",
               "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[32m'score'\u001b[0m: \u001b[32m'B'\u001b[0m,\n",
-              "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[32m'judge_feedback'\u001b[0m: \u001b[32m'Answer: B, Explanation: The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it. The EXPECTED_RESPONSE only mentions \"LoRA\", which is present in all the points of the GENERATED_RESPONSE. The GENERATED_RESPONSE provides more details and specific topics related to LoRA, but it does not contradict the EXPECTED_RESPONSE.'\u001b[0m\n",
+              "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[32m'judge_feedback'\u001b[0m: \u001b[32m'Answer: B, Explanation: The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it. The EXPECTED_RESPONSE only mentions \"LoRA\", which is a topic that is extensively covered in the GENERATED_RESPONSE. The GENERATED_RESPONSE provides more specific and detailed topics related to LoRA, but it does not contradict the EXPECTED_RESPONSE.'\u001b[0m\n",
               "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1m}\u001b[0m\n",
               "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m\n",
               "\u001b[2;32m│   │   \u001b[0m\u001b[1m)\u001b[0m,\n",
@@ -4129,11 +2765,11 @@
         }
       ],
       "source": [
-        "# NBVAL_SKIP\n",
         "import rich\n",
         "from rich.pretty import pprint\n",
         "\n",
-        "judge_model_id = \"meta-llama/Llama-3.1-405B-Instruct-FP8\"\n",
+        "# could even use larger models like 405B\n",
+        "judge_model_id = \"meta-llama/Llama-3.3-70B-Instruct\"\n",
         "\n",
         "JUDGE_PROMPT = \"\"\"\n",
         "Given a QUESTION and GENERATED_RESPONSE and EXPECTED_RESPONSE.\n",
@@ -4211,7 +2847,7 @@
     },
     {
       "cell_type": "code",
-      "execution_count": 1,
+      "execution_count": 29,
       "id": "44e05e16",
       "metadata": {},
       "outputs": [
@@ -4221,17 +2857,37 @@
           "text": [
             "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n",
             "                                 Dload  Upload   Total   Spent    Left  Speed\n",
-            "100  275k  100  275k    0     0   905k      0 --:--:-- --:--:-- --:--:--  906k\n"
+            "100  275k  100  275k    0     0   901k      0 --:--:-- --:--:-- --:--:--  903k\n"
           ]
+        },
+        {
+          "data": {
+            "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4QmWaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOmlwdGNFeHQ9Imh0dHA6Ly9pcHRjLm9yZy9zdGQvSXB0YzR4bXBFeHQvMjAwOC0wMi0yOS8iIGlwdGNFeHQ6RGlnaXRhbFNvdXJjZVR5cGU9InRyYWluZWRBbGdvcml0aG1pY01lZGlhIi8+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/Pv/bAEMAAgEBAQEBAgEBAQICAgICBAMCAgICBQQEAwQGBQYGBgUGBgYHCQgGBwkHBgYICwgJCgoKCgoGCAsMCwoMCQoKCv/bAEMBAgICAgICBQMDBQoHBgcKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCv/AABEIAwADAAMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYT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",
+            "text/plain": [
+              ""
+            ]
+          },
+          "execution_count": 29,
+          "metadata": {
+            "image/jpeg": {
+              "height": 256,
+              "width": 256
+            }
+          },
+          "output_type": "execute_result"
         }
       ],
       "source": [
-        "!curl -O https://raw.githubusercontent.com/meta-llama/llama-models/refs/heads/main/Llama_Repo.jpeg"
+        "!curl -O https://raw.githubusercontent.com/meta-llama/llama-models/refs/heads/main/Llama_Repo.jpeg\n",
+        "\n",
+        "from IPython.display import Image\n",
+        "Image(\"Llama_Repo.jpeg\", width=256, height=256)\n",
+        "\n"
       ]
     },
     {
       "cell_type": "code",
-      "execution_count": 20,
+      "execution_count": 30,
       "id": "a2c1e1c2",
       "metadata": {},
       "outputs": [],
@@ -4251,14 +2907,12 @@
       "id": "7737cd41",
       "metadata": {},
       "source": [
-        "### 4.2 Using Llama Stack Chat API\n",
-        "\n",
-        "The code below uses the Llama Stack 0.1's chat API to interact with Llama 3.2:"
+        "### 4.2 Using Llama Stack Inference API for multimodal inference"
       ]
     },
     {
       "cell_type": "code",
-      "execution_count": 21,
+      "execution_count": 31,
       "id": "d7914894",
       "metadata": {},
       "outputs": [
@@ -4298,65 +2952,6 @@
         "print(response.completion_message.content)"
       ]
     },
-    {
-      "cell_type": "markdown",
-      "id": "e741d7b9",
-      "metadata": {},
-      "source": [
-        "### 4.3 Using Llama Stack Agent API\n",
-        "\n",
-        "The code below uses the Llama Stack 0.1's Agent API to interact with Llama 3.2:"
-      ]
-    },
-    {
-      "cell_type": "code",
-      "execution_count": 19,
-      "id": "f9a83275",
-      "metadata": {},
-      "outputs": [
-        {
-          "name": "stdout",
-          "output_type": "stream",
-          "text": [
-            "\u001b[33minference> \u001b[0m\u001b[33mThere\u001b[0m\u001b[33m are\u001b[0m\u001b[33m three\u001b[0m\u001b[33m different\u001b[0m\u001b[33m colors\u001b[0m\u001b[33m of\u001b[0m\u001b[33m ll\u001b[0m\u001b[33mamas\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m image\u001b[0m\u001b[33m.\u001b[0m\u001b[33m The\u001b[0m\u001b[33m first\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m on\u001b[0m\u001b[33m the\u001b[0m\u001b[33m left\u001b[0m\u001b[33m is\u001b[0m\u001b[33m white\u001b[0m\u001b[33m,\u001b[0m\u001b[33m the\u001b[0m\u001b[33m second\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m middle\u001b[0m\u001b[33m is\u001b[0m\u001b[33m purple\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m the\u001b[0m\u001b[33m third\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m on\u001b[0m\u001b[33m the\u001b[0m\u001b[33m right\u001b[0m\u001b[33m is\u001b[0m\u001b[33m white\u001b[0m\u001b[33m with\u001b[0m\u001b[33m a\u001b[0m\u001b[33m blue\u001b[0m\u001b[33m party\u001b[0m\u001b[33m hat\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n",
-            "\u001b[30m\u001b[0m"
-          ]
-        }
-      ],
-      "source": [
-        "agent = Agent(\n",
-        "    client, \n",
-        "    model=vision_model_id,\n",
-        "    instructions=\"You are a helpful assistant\",\n",
-        ")\n",
-        "session_id = agent.create_session(\"test-session\")\n",
-        "\n",
-        "response = agent.create_turn(\n",
-        "    messages=[{\n",
-        "        \"role\": \"user\",\n",
-        "        \"content\": [\n",
-        "            {\n",
-        "                \"type\": \"image\",\n",
-        "                \"image\": {\n",
-        "                        \"url\": {\n",
-        "                            \"uri\": encode_image(\"Llama_Repo.jpeg\")\n",
-        "                        }\n",
-        "                }\n",
-        "            },\n",
-        "            {\n",
-        "                \"type\": \"text\",\n",
-        "                \"text\": \"How many different colors are those llamas? What are those colors?\",\n",
-        "            }\n",
-        "        ]\n",
-        "    }],\n",
-        "    session_id=session_id,\n",
-        ")\n",
-        "\n",
-        "for log in AgentEventLogger().log(response):\n",
-        "    log.print()\n",
-        "    "
-      ]
-    },
     {
       "cell_type": "code",
       "execution_count": null,
@@ -4373,7 +2968,7 @@
       "provenance": []
     },
     "kernelspec": {
-      "display_name": "master",
+      "display_name": "Python 3",
       "language": "python",
       "name": "python3"
     },
diff --git a/llama_stack/cli/stack/run.py b/llama_stack/cli/stack/run.py
index 57a0b28cc..88c3b061a 100644
--- a/llama_stack/cli/stack/run.py
+++ b/llama_stack/cli/stack/run.py
@@ -43,7 +43,7 @@ class StackRun(Subcommand):
         self.parser.add_argument(
             "--image-name",
             type=str,
-            default=os.environ.get("CONDA_DEFAULT_ENV"),
+            default=None,
             help="Name of the image to run. Defaults to the current conda environment",
         )
         self.parser.add_argument(
diff --git a/llama_stack/distribution/start_stack.sh b/llama_stack/distribution/start_stack.sh
index cfc078c27..964fcfaf7 100755
--- a/llama_stack/distribution/start_stack.sh
+++ b/llama_stack/distribution/start_stack.sh
@@ -13,6 +13,7 @@ LLAMA_CHECKPOINT_DIR=${LLAMA_CHECKPOINT_DIR:-}
 LLAMA_STACK_DIR=${LLAMA_STACK_DIR:-}
 TEST_PYPI_VERSION=${TEST_PYPI_VERSION:-}
 PYPI_VERSION=${PYPI_VERSION:-}
+VIRTUAL_ENV=${VIRTUAL_ENV:-}
 
 set -euo pipefail
 
@@ -69,22 +70,25 @@ while [[ $# -gt 0 ]]; do
     ;;
   esac
 done
-
 PYTHON_BINARY="python"
 case "$env_type" in
   "venv")
-    # Activate virtual environment
-    if [ ! -d "$env_path_or_name" ]; then
-        echo -e "${RED}Error: Virtual environment not found at $env_path_or_name${NC}" >&2
-        exit 1
-    fi
+    if [ -n "$VIRTUAL_ENV" && "$VIRTUAL_ENV" == "$env_path_or_name" ]; then
+        echo -e "${GREEN}Virtual environment already activated${NC}" >&2
+    else
+        # Activate virtual environment
+        if [ ! -d "$env_path_or_name" ]; then
+            echo -e "${RED}Error: Virtual environment not found at $env_path_or_name${NC}" >&2
+            exit 1
+        fi
 
-    if [ ! -f "$env_path_or_name/bin/activate" ]; then
-        echo -e "${RED}Error: Virtual environment activate binary not found at $env_path_or_name/bin/activate" >&2
-        exit 1
-    fi
+        if [ ! -f "$env_path_or_name/bin/activate" ]; then
+            echo -e "${RED}Error: Virtual environment activate binary not found at $env_path_or_name/bin/activate" >&2
+            exit 1
+        fi
 
-    source "$env_path_or_name/bin/activate"
+        source "$env_path_or_name/bin/activate"
+    fi
     ;;
   "conda")
     if ! is_command_available conda; then
diff --git a/llama_stack/distribution/utils/context.py b/llama_stack/distribution/utils/context.py
index 2f32afba2..fcc72161d 100644
--- a/llama_stack/distribution/utils/context.py
+++ b/llama_stack/distribution/utils/context.py
@@ -18,15 +18,19 @@ def preserve_contexts_async_generator(
     This is needed because we start a new asyncio event loop for each streaming request,
     and we need to preserve the context across the event loop boundary.
     """
+    # Capture initial context values
+    initial_context_values = {context_var.name: context_var.get() for context_var in context_vars}
 
     async def wrapper() -> AsyncGenerator[T, None]:
         while True:
             try:
-                item = await gen.__anext__()
-                context_values = {context_var.name: context_var.get() for context_var in context_vars}
-                yield item
+                # Restore context values before any await
                 for context_var in context_vars:
-                    _ = context_var.set(context_values[context_var.name])
+                    context_var.set(initial_context_values[context_var.name])
+
+                item = await gen.__anext__()
+                yield item
+
             except StopAsyncIteration:
                 break
 

From e8d59590480f3971e5f087e072ea8717bc2a3b88 Mon Sep 17 00:00:00 2001
From: Hardik Shah 
Date: Wed, 26 Mar 2025 12:54:21 -0700
Subject: [PATCH 12/45] fix: update getting_started.ipynb (#1797)

using simple `pip install llama-stack-client`
---
 docs/getting_started.ipynb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb
index f13a26a5a..d86fa6dfd 100644
--- a/docs/getting_started.ipynb
+++ b/docs/getting_started.ipynb
@@ -235,7 +235,7 @@
         }
       ],
       "source": [
-        "!uv pip install -U llama-stack-client"
+        "!pip install -U llama-stack-client"
       ]
     },
     {

From f8445b0d695677bb71f7429379caf18cfe6003e2 Mon Sep 17 00:00:00 2001
From: Hardik Shah 
Date: Wed, 26 Mar 2025 14:47:32 -0700
Subject: [PATCH 13/45] fix: update mcp commands in getting_started.ipynb
 (#1800)

as titled
---
 docs/getting_started.ipynb | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb
index d86fa6dfd..a8a4b9401 100644
--- a/docs/getting_started.ipynb
+++ b/docs/getting_started.ipynb
@@ -1792,10 +1792,10 @@
       "source": [
         "# NBVAL_SKIP\n",
         "%xterm\n",
-        "# touch /tmp/content/foo\n",
-        "# echo hello > /tmp/content/foo\n",
-        "# touch /tmp/content/bar\n",
-        "# npx -y supergateway --port 8000 --stdio 'npx -y @modelcontextprotocol/server-filesystem /tmp/content'"
+        "# touch /content/foo\n",
+        "# echo hello > /content/foo\n",
+        "# touch /content/bar\n",
+        "# npx -y supergateway --port 8000 --stdio 'npx -y @modelcontextprotocol/server-filesystem /content'"
       ]
     },
     {
@@ -2225,7 +2225,7 @@
         ")\n",
         "user_prompts = [\n",
         "    \"Hello\",\n",
-        "    \"Whats written in /tmp/content/foo ?\",\n",
+        "    \"Whats written in /content/foo ?\",\n",
         "]\n",
         "\n",
         "session_id = agent.create_session(\"test-session\")\n",

From 742020b94ac94cd481ec8c6729d2944c9bc22643 Mon Sep 17 00:00:00 2001
From: Xi Yan 
Date: Wed, 26 Mar 2025 15:07:54 -0700
Subject: [PATCH 14/45] chore: remove distributions folder (#1801)

# What does this PR do?

- the distribution folder is referencing template, and have dead docker
compose scripts

[//]: # (If resolving an issue, uncomment and update the line below)
[//]: # (Closes #[issue-number])

## Test Plan


[//]: # (## Documentation)
---
 distributions/bedrock/build.yaml              |   1 -
 distributions/bedrock/compose.yaml            |  15 ---
 distributions/bedrock/run.yaml                |   1 -
 distributions/cerebras/build.yaml             |   1 -
 distributions/cerebras/compose.yaml           |  16 ---
 distributions/cerebras/run.yaml               |   1 -
 distributions/dell-tgi/compose.yaml           |  50 ---------
 distributions/dell-tgi/run.yaml               |  44 --------
 distributions/fireworks/build.yaml            |   1 -
 distributions/fireworks/compose.yaml          |  14 ---
 distributions/fireworks/run.yaml              |   1 -
 distributions/meta-reference-gpu/build.yaml   |   1 -
 distributions/meta-reference-gpu/compose.yaml |  34 ------
 .../meta-reference-gpu/run-with-safety.yaml   |   1 -
 distributions/meta-reference-gpu/run.yaml     |   1 -
 .../meta-reference-quantized-gpu/build.yaml   |   1 -
 .../meta-reference-quantized-gpu/compose.yaml |  35 ------
 .../meta-reference-quantized-gpu/run.yaml     |  58 ----------
 distributions/ollama/build.yaml               |   1 -
 distributions/ollama/compose.yaml             |  71 ------------
 distributions/ollama/pull-models.sh           |  18 ---
 distributions/ollama/run-with-safety.yaml     |   1 -
 distributions/ollama/run.yaml                 |   1 -
 distributions/ramalama/faiss_store.db         | Bin 12288 -> 0 bytes
 distributions/remote-nvidia/build.yaml        |   1 -
 distributions/remote-nvidia/compose.yaml      |  19 ----
 distributions/remote-nvidia/run.yaml          |   1 -
 distributions/remote-vllm/build.yaml          |   1 -
 distributions/remote-vllm/compose.yaml        |  99 -----------------
 .../remote-vllm/run-with-safety.yaml          |   1 -
 distributions/remote-vllm/run.yaml            |   1 -
 distributions/runpod/build.yaml               |   9 --
 distributions/sambanova/build.yaml            |   1 -
 distributions/sambanova/compose.yaml          |  16 ---
 distributions/sambanova/run.yaml              |   1 -
 distributions/tgi/build.yaml                  |   1 -
 distributions/tgi/compose.yaml                | 103 ------------------
 distributions/tgi/run-with-safety.yaml        |   1 -
 distributions/tgi/run.yaml                    |   1 -
 distributions/together/build.yaml             |   1 -
 distributions/together/compose.yaml           |  14 ---
 distributions/together/run.yaml               |   1 -
 distributions/vllm-gpu/build.yaml             |   1 -
 distributions/vllm-gpu/compose.yaml           |  35 ------
 distributions/vllm-gpu/run.yaml               |  66 -----------
 45 files changed, 742 deletions(-)
 delete mode 120000 distributions/bedrock/build.yaml
 delete mode 100644 distributions/bedrock/compose.yaml
 delete mode 120000 distributions/bedrock/run.yaml
 delete mode 120000 distributions/cerebras/build.yaml
 delete mode 100644 distributions/cerebras/compose.yaml
 delete mode 120000 distributions/cerebras/run.yaml
 delete mode 100644 distributions/dell-tgi/compose.yaml
 delete mode 100644 distributions/dell-tgi/run.yaml
 delete mode 120000 distributions/fireworks/build.yaml
 delete mode 100644 distributions/fireworks/compose.yaml
 delete mode 120000 distributions/fireworks/run.yaml
 delete mode 120000 distributions/meta-reference-gpu/build.yaml
 delete mode 100644 distributions/meta-reference-gpu/compose.yaml
 delete mode 120000 distributions/meta-reference-gpu/run-with-safety.yaml
 delete mode 120000 distributions/meta-reference-gpu/run.yaml
 delete mode 120000 distributions/meta-reference-quantized-gpu/build.yaml
 delete mode 100644 distributions/meta-reference-quantized-gpu/compose.yaml
 delete mode 100644 distributions/meta-reference-quantized-gpu/run.yaml
 delete mode 120000 distributions/ollama/build.yaml
 delete mode 100644 distributions/ollama/compose.yaml
 delete mode 100755 distributions/ollama/pull-models.sh
 delete mode 120000 distributions/ollama/run-with-safety.yaml
 delete mode 120000 distributions/ollama/run.yaml
 delete mode 100644 distributions/ramalama/faiss_store.db
 delete mode 120000 distributions/remote-nvidia/build.yaml
 delete mode 100644 distributions/remote-nvidia/compose.yaml
 delete mode 120000 distributions/remote-nvidia/run.yaml
 delete mode 120000 distributions/remote-vllm/build.yaml
 delete mode 100644 distributions/remote-vllm/compose.yaml
 delete mode 120000 distributions/remote-vllm/run-with-safety.yaml
 delete mode 120000 distributions/remote-vllm/run.yaml
 delete mode 100644 distributions/runpod/build.yaml
 delete mode 100644 distributions/sambanova/build.yaml
 delete mode 100644 distributions/sambanova/compose.yaml
 delete mode 100644 distributions/sambanova/run.yaml
 delete mode 120000 distributions/tgi/build.yaml
 delete mode 100644 distributions/tgi/compose.yaml
 delete mode 120000 distributions/tgi/run-with-safety.yaml
 delete mode 120000 distributions/tgi/run.yaml
 delete mode 120000 distributions/together/build.yaml
 delete mode 100644 distributions/together/compose.yaml
 delete mode 120000 distributions/together/run.yaml
 delete mode 120000 distributions/vllm-gpu/build.yaml
 delete mode 100644 distributions/vllm-gpu/compose.yaml
 delete mode 100644 distributions/vllm-gpu/run.yaml

diff --git a/distributions/bedrock/build.yaml b/distributions/bedrock/build.yaml
deleted file mode 120000
index 72402ef8d..000000000
--- a/distributions/bedrock/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/bedrock/build.yaml
\ No newline at end of file
diff --git a/distributions/bedrock/compose.yaml b/distributions/bedrock/compose.yaml
deleted file mode 100644
index 055b92c67..000000000
--- a/distributions/bedrock/compose.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-services:
-  llamastack:
-    image: distribution-bedrock
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run.yaml:/root/llamastack-run-bedrock.yaml
-    ports:
-      - "8321:8321"
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --yaml_config /root/llamastack-run-bedrock.yaml"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/bedrock/run.yaml b/distributions/bedrock/run.yaml
deleted file mode 120000
index f38abfc4e..000000000
--- a/distributions/bedrock/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/bedrock/run.yaml
\ No newline at end of file
diff --git a/distributions/cerebras/build.yaml b/distributions/cerebras/build.yaml
deleted file mode 120000
index bccbbcf60..000000000
--- a/distributions/cerebras/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/cerebras/build.yaml
\ No newline at end of file
diff --git a/distributions/cerebras/compose.yaml b/distributions/cerebras/compose.yaml
deleted file mode 100644
index 8dc09a865..000000000
--- a/distributions/cerebras/compose.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-cerebras
-    network_mode: "host"
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run.yaml:/root/llamastack-run-cerebras.yaml
-    ports:
-      - "8321:8321"
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --yaml_config /root/llamastack-run-cerebras.yaml"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/cerebras/run.yaml b/distributions/cerebras/run.yaml
deleted file mode 120000
index 9f9d20b4b..000000000
--- a/distributions/cerebras/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/cerebras/run.yaml
\ No newline at end of file
diff --git a/distributions/dell-tgi/compose.yaml b/distributions/dell-tgi/compose.yaml
deleted file mode 100644
index d26636cbd..000000000
--- a/distributions/dell-tgi/compose.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-services:
-  text-generation-inference:
-    image: registry.dell.huggingface.co/enterprise-dell-inference-meta-llama-meta-llama-3.1-8b-instruct
-    network_mode: "host"
-    volumes:
-      - $HOME/.cache/huggingface:/data
-    ports:
-      - "5009:5009"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=0,1,2,3,4
-      - NUM_SHARD=4
-      - MAX_BATCH_PREFILL_TOKENS=32768
-      - MAX_INPUT_TOKENS=8000
-      - MAX_TOTAL_TOKENS=8192
-    command: []
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            # that's the closest analogue to --gpus; provide
-            # an integer amount of devices or 'all'
-            count: all
-            # Devices are reserved using a list of capabilities, making
-            # capabilities the only required field. A device MUST
-            # satisfy all the requested capabilities for a successful
-            # reservation.
-            capabilities: [gpu]
-    runtime: nvidia
-  llamastack:
-    depends_on:
-      text-generation-inference:
-        condition: service_healthy
-    image: llamastack/distribution-tgi
-    network_mode: "host"
-    volumes:
-      - ~/.llama:/root/.llama
-      # Link to TGI run.yaml file
-      - ./run.yaml:/root/my-run.yaml
-    ports:
-      - "8321:8321"
-    # Hack: wait for TGI server to start before starting docker
-    entrypoint: bash -c "sleep 60; python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
-    restart_policy:
-      condition: on-failure
-      delay: 3s
-      max_attempts: 5
-      window: 60s
diff --git a/distributions/dell-tgi/run.yaml b/distributions/dell-tgi/run.yaml
deleted file mode 100644
index cd6ddcfdf..000000000
--- a/distributions/dell-tgi/run.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-version: '2'
-image_name: local
-container_image: null
-conda_env: local
-apis:
-- shields
-- agents
-- models
-- memory
-- memory_banks
-- inference
-- safety
-providers:
-  inference:
-  - provider_id: tgi0
-    provider_type: remote::tgi
-    config:
-      url: http://127.0.0.1:80
-  safety:
-  - provider_id: meta0
-    provider_type: inline::llama-guard
-    config:
-      model: Llama-Guard-3-1B
-      excluded_categories: []
-  - provider_id: meta1
-    provider_type: inline::prompt-guard
-    config:
-      model: Prompt-Guard-86M
-  memory:
-  - provider_id: meta0
-    provider_type: inline::faiss
-    config: {}
-  agents:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config:
-      persistence_store:
-        namespace: null
-        type: sqlite
-        db_path: ~/.llama/runtime/kvstore.db
-  telemetry:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config: {}
diff --git a/distributions/fireworks/build.yaml b/distributions/fireworks/build.yaml
deleted file mode 120000
index 32a5bd869..000000000
--- a/distributions/fireworks/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/fireworks/build.yaml
\ No newline at end of file
diff --git a/distributions/fireworks/compose.yaml b/distributions/fireworks/compose.yaml
deleted file mode 100644
index 84b8491e4..000000000
--- a/distributions/fireworks/compose.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-fireworks
-    ports:
-      - "8321:8321"
-    environment:
-      - FIREWORKS_API_KEY=${FIREWORKS_API_KEY}
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --template fireworks"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/fireworks/run.yaml b/distributions/fireworks/run.yaml
deleted file mode 120000
index 532e0e2a8..000000000
--- a/distributions/fireworks/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/fireworks/run.yaml
\ No newline at end of file
diff --git a/distributions/meta-reference-gpu/build.yaml b/distributions/meta-reference-gpu/build.yaml
deleted file mode 120000
index 4418195eb..000000000
--- a/distributions/meta-reference-gpu/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/meta-reference-gpu/build.yaml
\ No newline at end of file
diff --git a/distributions/meta-reference-gpu/compose.yaml b/distributions/meta-reference-gpu/compose.yaml
deleted file mode 100644
index d977e92ea..000000000
--- a/distributions/meta-reference-gpu/compose.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-meta-reference-gpu
-    network_mode: "host"
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run.yaml:/root/my-run.yaml
-    ports:
-      - "8321:8321"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=0
-    command: []
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            # that's the closest analogue to --gpus; provide
-            # an integer amount of devices or 'all'
-            count: 1
-            # Devices are reserved using a list of capabilities, making
-            # capabilities the only required field. A device MUST
-            # satisfy all the requested capabilities for a successful
-            # reservation.
-            capabilities: [gpu]
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
-    runtime: nvidia
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
diff --git a/distributions/meta-reference-gpu/run-with-safety.yaml b/distributions/meta-reference-gpu/run-with-safety.yaml
deleted file mode 120000
index 4c5483425..000000000
--- a/distributions/meta-reference-gpu/run-with-safety.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/meta-reference-gpu/run-with-safety.yaml
\ No newline at end of file
diff --git a/distributions/meta-reference-gpu/run.yaml b/distributions/meta-reference-gpu/run.yaml
deleted file mode 120000
index d680186ab..000000000
--- a/distributions/meta-reference-gpu/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/meta-reference-gpu/run.yaml
\ No newline at end of file
diff --git a/distributions/meta-reference-quantized-gpu/build.yaml b/distributions/meta-reference-quantized-gpu/build.yaml
deleted file mode 120000
index f3dbe996f..000000000
--- a/distributions/meta-reference-quantized-gpu/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/meta-reference-quantized-gpu/build.yaml
\ No newline at end of file
diff --git a/distributions/meta-reference-quantized-gpu/compose.yaml b/distributions/meta-reference-quantized-gpu/compose.yaml
deleted file mode 100644
index 98e943dce..000000000
--- a/distributions/meta-reference-quantized-gpu/compose.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-meta-reference-quantized-gpu
-    network_mode: "host"
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run.yaml:/root/my-run.yaml
-    ports:
-      - "8321:8321"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=0
-    command: []
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            # that's the closest analogue to --gpus; provide
-            # an integer amount of devices or 'all'
-            count: 1
-            # Devices are reserved using a list of capabilities, making
-            # capabilities the only required field. A device MUST
-            # satisfy all the requested capabilities for a successful
-            # reservation.
-            capabilities: [gpu]
-    runtime: nvidia
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/meta-reference-quantized-gpu/run.yaml b/distributions/meta-reference-quantized-gpu/run.yaml
deleted file mode 100644
index eb631adaa..000000000
--- a/distributions/meta-reference-quantized-gpu/run.yaml
+++ /dev/null
@@ -1,58 +0,0 @@
-version: '2'
-image_name: local
-container_image: null
-conda_env: local
-apis:
-- shields
-- agents
-- models
-- memory
-- memory_banks
-- inference
-- safety
-providers:
-  inference:
-  - provider_id: meta0
-    provider_type: inline::meta-reference-quantized
-    config:
-      model: Llama3.2-3B-Instruct:int4-qlora-eo8
-      quantization:
-        type: int4
-      torch_seed: null
-      max_seq_len: 2048
-      max_batch_size: 1
-  - provider_id: meta1
-    provider_type: inline::meta-reference-quantized
-    config:
-      # not a quantized model !
-      model: Llama-Guard-3-1B
-      quantization: null
-      torch_seed: null
-      max_seq_len: 2048
-      max_batch_size: 1
-  safety:
-  - provider_id: meta0
-    provider_type: inline::llama-guard
-    config:
-      model: Llama-Guard-3-1B
-      excluded_categories: []
-  - provider_id: meta1
-    provider_type: inline::prompt-guard
-    config:
-      model: Prompt-Guard-86M
-  memory:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config: {}
-  agents:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config:
-      persistence_store:
-        namespace: null
-        type: sqlite
-        db_path: ~/.llama/runtime/kvstore.db
-  telemetry:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config: {}
diff --git a/distributions/ollama/build.yaml b/distributions/ollama/build.yaml
deleted file mode 120000
index 8772548e0..000000000
--- a/distributions/ollama/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/ollama/build.yaml
\ No newline at end of file
diff --git a/distributions/ollama/compose.yaml b/distributions/ollama/compose.yaml
deleted file mode 100644
index 06e6c1359..000000000
--- a/distributions/ollama/compose.yaml
+++ /dev/null
@@ -1,71 +0,0 @@
-services:
-  ollama:
-    image: ollama/ollama:latest
-    network_mode: ${NETWORK_MODE:-bridge}
-    volumes:
-      - ~/.ollama:/root/.ollama
-    ports:
-      - "11434:11434"
-    environment:
-      OLLAMA_DEBUG: 1
-    command: []
-    deploy:
-      resources:
-        limits:
-          memory: 8G    # Set maximum memory
-        reservations:
-          memory: 8G    # Set minimum memory reservation
-    # healthcheck:
-    #   # ugh, no CURL in ollama image
-    #   test: ["CMD", "curl", "-f", "http://ollama:11434"]
-    #   interval: 10s
-    #   timeout: 5s
-    #   retries: 5
-
-  ollama-init:
-    image: ollama/ollama:latest
-    depends_on:
-      - ollama
-        # condition: service_healthy
-    network_mode: ${NETWORK_MODE:-bridge}
-    environment:
-      - OLLAMA_HOST=ollama
-      - INFERENCE_MODEL=${INFERENCE_MODEL}
-      - SAFETY_MODEL=${SAFETY_MODEL:-}
-    volumes:
-      - ~/.ollama:/root/.ollama
-      - ./pull-models.sh:/pull-models.sh
-    entrypoint: ["/pull-models.sh"]
-
-  llamastack:
-    depends_on:
-      ollama:
-        condition: service_started
-      ollama-init:
-        condition: service_started
-    image: ${LLAMA_STACK_IMAGE:-llamastack/distribution-ollama}
-    network_mode: ${NETWORK_MODE:-bridge}
-    volumes:
-      - ~/.llama:/root/.llama
-      # Link to ollama run.yaml file
-      - ~/local/llama-stack/:/app/llama-stack-source
-      - ./run${SAFETY_MODEL:+-with-safety}.yaml:/root/my-run.yaml
-    ports:
-      - "${LLAMA_STACK_PORT:-8321}:${LLAMA_STACK_PORT:-8321}"
-    environment:
-      - INFERENCE_MODEL=${INFERENCE_MODEL}
-      - SAFETY_MODEL=${SAFETY_MODEL:-}
-      - OLLAMA_URL=http://ollama:11434
-    entrypoint: >
-        python -m llama_stack.distribution.server.server /root/my-run.yaml \
-        --port ${LLAMA_STACK_PORT:-8321}
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 10s
-        max_attempts: 3
-        window: 60s
-volumes:
-  ollama:
-  ollama-init:
-  llamastack:
diff --git a/distributions/ollama/pull-models.sh b/distributions/ollama/pull-models.sh
deleted file mode 100755
index fb5bf8a4a..000000000
--- a/distributions/ollama/pull-models.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) Meta Platforms, Inc. and affiliates.
-# All rights reserved.
-#
-# This source code is licensed under the terms described in the LICENSE file in
-# the root directory of this source tree.
-
-echo "Preloading (${INFERENCE_MODEL}, ${SAFETY_MODEL})..."
-for model in ${INFERENCE_MODEL} ${SAFETY_MODEL}; do
-  echo "Preloading $model..."
-  if ! ollama run "$model"; then
-    echo "Failed to pull and run $model"
-    exit 1
-  fi
-done
-
-echo "All models pulled successfully"
diff --git a/distributions/ollama/run-with-safety.yaml b/distributions/ollama/run-with-safety.yaml
deleted file mode 120000
index 5695b49e7..000000000
--- a/distributions/ollama/run-with-safety.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/ollama/run-with-safety.yaml
\ No newline at end of file
diff --git a/distributions/ollama/run.yaml b/distributions/ollama/run.yaml
deleted file mode 120000
index b008b1bf4..000000000
--- a/distributions/ollama/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/ollama/run.yaml
\ No newline at end of file
diff --git a/distributions/ramalama/faiss_store.db b/distributions/ramalama/faiss_store.db
deleted file mode 100644
index 573e60e9016d6aad4fdac203452cfb33084c8157..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12288
zcmeI#F-yZh6bJBkQB(>g**au-qk;+|I2+3i#Rh76Lpy~NPY8{Trq@yzLBE~f$kAL#
zCIj6Z%KyRLtIKzVpv#Y0
z-~S=c56BPv?_CE_hX4d1009U<00Izz00bZa0SNquz~_xP9)zLz8e09Bo5f~ji?Ut3
zVIm_XSw(ka$xV$-93^wUm-F+^og1C6O})3fZnm#ksclv)S&d>j
zRZ%?o^P;m0?`RN(g0kh4*{
-      --gpu-memory-utilization 0.75
-      --model ${VLLM_INFERENCE_MODEL:-meta-llama/Llama-3.2-3B-Instruct}
-      --enforce-eager
-      --max-model-len 8192
-      --max-num-seqs 16
-      --port ${VLLM_INFERENCE_PORT:-5100}
-    healthcheck:
-      test: ["CMD", "curl", "-f", "http://localhost:${VLLM_INFERENCE_PORT:-5100}/v1/health"]
-      interval: 30s
-      timeout: 10s
-      retries: 5
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            capabilities: [gpu]
-    runtime: nvidia
-
-  # A little trick:
-  # if VLLM_SAFETY_MODEL is set, we will create a service for the safety model
-  # otherwise, the entry will end in a hyphen which gets ignored by docker compose
-  vllm-${VLLM_SAFETY_MODEL:+safety}:
-    image: vllm/vllm-openai:latest
-    volumes:
-      - $HOME/.cache/huggingface:/root/.cache/huggingface
-    network_mode: ${NETWORK_MODE:-bridged}
-    ports:
-      - "${VLLM_SAFETY_PORT:-5101}:${VLLM_SAFETY_PORT:-5101}"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=${VLLM_SAFETY_GPU:-1}
-      - HUGGING_FACE_HUB_TOKEN=$HF_TOKEN
-    command: >
-      --gpu-memory-utilization 0.75
-      --model ${VLLM_SAFETY_MODEL}
-      --enforce-eager
-      --max-model-len 8192
-      --max-num-seqs 16
-      --port ${VLLM_SAFETY_PORT:-5101}
-    healthcheck:
-      test: ["CMD", "curl", "-f", "http://localhost:${VLLM_SAFETY_PORT:-5101}/v1/health"]
-      interval: 30s
-      timeout: 10s
-      retries: 5
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            capabilities: [gpu]
-    runtime: nvidia
-  llamastack:
-    depends_on:
-      - vllm-inference:
-          condition: service_healthy
-      - vllm-${VLLM_SAFETY_MODEL:+safety}:
-          condition: service_healthy
-    image: llamastack/distribution-remote-vllm:test-0.0.52rc3
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run${VLLM_SAFETY_MODEL:+-with-safety}.yaml:/root/llamastack-run-remote-vllm.yaml
-    network_mode: ${NETWORK_MODE:-bridged}
-    environment:
-      - VLLM_URL=http://vllm-inference:${VLLM_INFERENCE_PORT:-5100}/v1
-      - VLLM_SAFETY_URL=http://vllm-safety:${VLLM_SAFETY_PORT:-5101}/v1
-      - INFERENCE_MODEL=${INFERENCE_MODEL:-meta-llama/Llama-3.2-3B-Instruct}
-      - MAX_TOKENS=${MAX_TOKENS:-4096}
-      - SQLITE_STORE_DIR=${SQLITE_STORE_DIR:-$HOME/.llama/distributions/remote-vllm}
-      - SAFETY_MODEL=${SAFETY_MODEL:-meta-llama/Llama-Guard-3-1B}
-    ports:
-      - "${LLAMA_STACK_PORT:-8321}:${LLAMA_STACK_PORT:-8321}"
-    # Hack: wait for vLLM server to start before starting docker
-    entrypoint: bash -c "sleep 60; python -m llama_stack.distribution.server.server --yaml_config /root/llamastack-run-remote-vllm.yaml --port 8321"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
-volumes:
-  vllm-inference:
-  vllm-safety:
-  llamastack:
diff --git a/distributions/remote-vllm/run-with-safety.yaml b/distributions/remote-vllm/run-with-safety.yaml
deleted file mode 120000
index b2c3c36da..000000000
--- a/distributions/remote-vllm/run-with-safety.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/remote-vllm/run-with-safety.yaml
\ No newline at end of file
diff --git a/distributions/remote-vllm/run.yaml b/distributions/remote-vllm/run.yaml
deleted file mode 120000
index ac70c0e6a..000000000
--- a/distributions/remote-vllm/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/remote-vllm/run.yaml
\ No newline at end of file
diff --git a/distributions/runpod/build.yaml b/distributions/runpod/build.yaml
deleted file mode 100644
index 9348573ef..000000000
--- a/distributions/runpod/build.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-name: runpod
-distribution_spec:
-  description: Use Runpod for running LLM inference
-  providers:
-    inference: remote::runpod
-    memory: meta-reference
-    safety: meta-reference
-    agents: meta-reference
-    telemetry: meta-reference
diff --git a/distributions/sambanova/build.yaml b/distributions/sambanova/build.yaml
deleted file mode 100644
index dbf013d2d..000000000
--- a/distributions/sambanova/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/sambanova/build.yaml
diff --git a/distributions/sambanova/compose.yaml b/distributions/sambanova/compose.yaml
deleted file mode 100644
index 58b9fb1ef..000000000
--- a/distributions/sambanova/compose.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-sambanova
-    network_mode: "host"
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run.yaml:/root/llamastack-run-sambanova.yaml
-    ports:
-      - "5000:5000"
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --yaml_config /root/llamastack-run-sambanova.yaml"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/sambanova/run.yaml b/distributions/sambanova/run.yaml
deleted file mode 100644
index 385282c67..000000000
--- a/distributions/sambanova/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/sambanova/run.yaml
diff --git a/distributions/tgi/build.yaml b/distributions/tgi/build.yaml
deleted file mode 120000
index 73e59ad84..000000000
--- a/distributions/tgi/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/tgi/build.yaml
\ No newline at end of file
diff --git a/distributions/tgi/compose.yaml b/distributions/tgi/compose.yaml
deleted file mode 100644
index d7b3bc77e..000000000
--- a/distributions/tgi/compose.yaml
+++ /dev/null
@@ -1,103 +0,0 @@
-services:
-  tgi-inference:
-    image: ghcr.io/huggingface/text-generation-inference:latest
-    volumes:
-      - $HOME/.cache/huggingface:/data
-    network_mode: ${NETWORK_MODE:-bridged}
-    ports:
-       - "${TGI_INFERENCE_PORT:-8080}:${TGI_INFERENCE_PORT:-8080}"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=${TGI_INFERENCE_GPU:-0}
-      - HF_TOKEN=$HF_TOKEN
-      - HF_HOME=/data
-      - HF_DATASETS_CACHE=/data
-      - HF_MODULES_CACHE=/data
-      - HF_HUB_CACHE=/data
-    command: >
-      --dtype bfloat16
-      --usage-stats off
-      --sharded false
-      --model-id ${TGI_INFERENCE_MODEL:-meta-llama/Llama-3.2-3B-Instruct}
-      --port ${TGI_INFERENCE_PORT:-8080}
-      --cuda-memory-fraction 0.75
-    healthcheck:
-      test: ["CMD", "curl", "-f", "http://tgi-inference:${TGI_INFERENCE_PORT:-8080}/health"]
-      interval: 5s
-      timeout: 5s
-      retries: 30
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            capabilities: [gpu]
-    runtime: nvidia
-
-  tgi-${TGI_SAFETY_MODEL:+safety}:
-    image: ghcr.io/huggingface/text-generation-inference:latest
-    volumes:
-      - $HOME/.cache/huggingface:/data
-    network_mode: ${NETWORK_MODE:-bridged}
-    ports:
-       - "${TGI_SAFETY_PORT:-8081}:${TGI_SAFETY_PORT:-8081}"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=${TGI_SAFETY_GPU:-1}
-      - HF_TOKEN=$HF_TOKEN
-      - HF_HOME=/data
-      - HF_DATASETS_CACHE=/data
-      - HF_MODULES_CACHE=/data
-      - HF_HUB_CACHE=/data
-    command: >
-      --dtype bfloat16
-      --usage-stats off
-      --sharded false
-      --model-id ${TGI_SAFETY_MODEL:-meta-llama/Llama-Guard-3-1B}
-      --port ${TGI_SAFETY_PORT:-8081}
-      --cuda-memory-fraction 0.75
-    healthcheck:
-      test: ["CMD", "curl", "-f", "http://tgi-safety:${TGI_SAFETY_PORT:-8081}/health"]
-      interval: 5s
-      timeout: 5s
-      retries: 30
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            capabilities: [gpu]
-    runtime: nvidia
-
-  llamastack:
-    depends_on:
-      tgi-inference:
-        condition: service_healthy
-      tgi-${TGI_SAFETY_MODEL:+safety}:
-        condition: service_healthy
-    image: llamastack/distribution-tgi:test-0.0.52rc3
-    network_mode: ${NETWORK_MODE:-bridged}
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run${TGI_SAFETY_MODEL:+-with-safety}.yaml:/root/my-run.yaml
-    ports:
-      - "${LLAMA_STACK_PORT:-8321}:${LLAMA_STACK_PORT:-8321}"
-    # Hack: wait for TGI server to start before starting docker
-    entrypoint: bash -c "sleep 60; python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
-    restart_policy:
-      condition: on-failure
-      delay: 3s
-      max_attempts: 5
-      window: 60s
-    environment:
-      - TGI_URL=http://tgi-inference:${TGI_INFERENCE_PORT:-8080}
-      - SAFETY_TGI_URL=http://tgi-safety:${TGI_SAFETY_PORT:-8081}
-      - INFERENCE_MODEL=${INFERENCE_MODEL:-meta-llama/Llama-3.2-3B-Instruct}
-      - SAFETY_MODEL=${SAFETY_MODEL:-meta-llama/Llama-Guard-3-1B}
-
-volumes:
-  tgi-inference:
-  tgi-safety:
-  llamastack:
diff --git a/distributions/tgi/run-with-safety.yaml b/distributions/tgi/run-with-safety.yaml
deleted file mode 120000
index 62d26708e..000000000
--- a/distributions/tgi/run-with-safety.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/tgi/run-with-safety.yaml
\ No newline at end of file
diff --git a/distributions/tgi/run.yaml b/distributions/tgi/run.yaml
deleted file mode 120000
index f3cc3a502..000000000
--- a/distributions/tgi/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/tgi/run.yaml
\ No newline at end of file
diff --git a/distributions/together/build.yaml b/distributions/together/build.yaml
deleted file mode 120000
index 3877a9c96..000000000
--- a/distributions/together/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/together/build.yaml
\ No newline at end of file
diff --git a/distributions/together/compose.yaml b/distributions/together/compose.yaml
deleted file mode 100644
index f66ee69f9..000000000
--- a/distributions/together/compose.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-together
-    ports:
-      - "8321:8321"
-    environment:
-      - TOGETHER_API_KEY=${TOGETHER_API_KEY}
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --template together"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/together/run.yaml b/distributions/together/run.yaml
deleted file mode 120000
index 102d9866e..000000000
--- a/distributions/together/run.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/together/run.yaml
\ No newline at end of file
diff --git a/distributions/vllm-gpu/build.yaml b/distributions/vllm-gpu/build.yaml
deleted file mode 120000
index a95d34c1f..000000000
--- a/distributions/vllm-gpu/build.yaml
+++ /dev/null
@@ -1 +0,0 @@
-../../llama_stack/templates/inline-vllm/build.yaml
\ No newline at end of file
diff --git a/distributions/vllm-gpu/compose.yaml b/distributions/vllm-gpu/compose.yaml
deleted file mode 100644
index 98267cdc3..000000000
--- a/distributions/vllm-gpu/compose.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-services:
-  llamastack:
-    image: llamastack/distribution-inline-vllm
-    network_mode: "host"
-    volumes:
-      - ~/.llama:/root/.llama
-      - ./run.yaml:/root/my-run.yaml
-    ports:
-      - "8321:8321"
-    devices:
-      - nvidia.com/gpu=all
-    environment:
-      - CUDA_VISIBLE_DEVICES=0
-    command: []
-    deploy:
-      resources:
-        reservations:
-          devices:
-          - driver: nvidia
-            # that's the closest analogue to --gpus; provide
-            # an integer amount of devices or 'all'
-            count: 1
-            # Devices are reserved using a list of capabilities, making
-            # capabilities the only required field. A device MUST
-            # satisfy all the requested capabilities for a successful
-            # reservation.
-            capabilities: [gpu]
-    runtime: nvidia
-    entrypoint: bash -c "python -m llama_stack.distribution.server.server --yaml_config /root/my-run.yaml"
-    deploy:
-      restart_policy:
-        condition: on-failure
-        delay: 3s
-        max_attempts: 5
-        window: 60s
diff --git a/distributions/vllm-gpu/run.yaml b/distributions/vllm-gpu/run.yaml
deleted file mode 100644
index a75a4c451..000000000
--- a/distributions/vllm-gpu/run.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-version: '2'
-image_name: local
-container_image: null
-conda_env: local
-apis:
-- shields
-- agents
-- models
-- memory
-- memory_banks
-- inference
-- safety
-providers:
-  inference:
-  - provider_id: vllm-inference
-    provider_type: inline::vllm
-    config:
-      model: Llama3.2-3B-Instruct
-      tensor_parallel_size: 1
-      gpu_memory_utilization: 0.4
-      enforce_eager: true
-      max_tokens: 4096
-  - provider_id: vllm-inference-safety
-    provider_type: inline::vllm
-    config:
-      model: Llama-Guard-3-1B
-      tensor_parallel_size: 1
-      gpu_memory_utilization: 0.2
-      enforce_eager: true
-      max_tokens: 4096
-  safety:
-  - provider_id: meta0
-    provider_type: inline::llama-guard
-    config:
-      model: Llama-Guard-3-1B
-      excluded_categories: []
-  # Uncomment to use prompt guard
-  # - provider_id: meta1
-  #   provider_type: inline::prompt-guard
-  #   config:
-  #     model: Prompt-Guard-86M
-  memory:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config: {}
-  # Uncomment to use pgvector
-  # - provider_id: pgvector
-  #   provider_type: remote::pgvector
-  #   config:
-  #     host: 127.0.0.1
-  #     port: 5432
-  #     db: postgres
-  #     user: postgres
-  #     password: mysecretpassword
-  agents:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config:
-      persistence_store:
-        namespace: null
-        type: sqlite
-        db_path: ~/.llama/runtime/agents_store.db
-  telemetry:
-  - provider_id: meta0
-    provider_type: inline::meta-reference
-    config: {}

From 193e53121650700b4e3b435a4f1b12119b761386 Mon Sep 17 00:00:00 2001
From: Ihar Hrachyshka 
Date: Wed, 26 Mar 2025 18:22:17 -0400
Subject: [PATCH 15/45] chore: re-enable isort enforcement (#1802)

# What does this PR do?

Re-enable isort enforcement.

It was disabled in 1a73f8305b513b0880c7903d3458b4f89e45f3e3, probably by
mistake.

Signed-off-by: Ihar Hrachyshka 
---
 pyproject.toml                                            | 1 +
 tests/unit/providers/nvidia/conftest.py                   | 3 ++-
 tests/unit/providers/nvidia/test_parameters.py            | 5 +++--
 .../unit/providers/nvidia/test_supervised_fine_tuning.py  | 8 ++++----
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/pyproject.toml b/pyproject.toml
index 9eef66672..c1b6e101b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -132,6 +132,7 @@ select = [
     "N",   # Naming
     "W",   # Warnings
     "DTZ", # datetime rules
+    "I",   # isort (imports order)
 ]
 ignore = [
     # The following ignores are desired by the project maintainers.
diff --git a/tests/unit/providers/nvidia/conftest.py b/tests/unit/providers/nvidia/conftest.py
index 1c4a1d145..c43e1cd77 100644
--- a/tests/unit/providers/nvidia/conftest.py
+++ b/tests/unit/providers/nvidia/conftest.py
@@ -5,9 +5,10 @@
 # the root directory of this source tree.
 
 import asyncio
-import pytest
 from unittest.mock import AsyncMock, MagicMock, patch
 
+import pytest
+
 mock_session = MagicMock()
 mock_session.closed = False
 mock_session.close = AsyncMock()
diff --git a/tests/unit/providers/nvidia/test_parameters.py b/tests/unit/providers/nvidia/test_parameters.py
index bf579fbfb..cb1b92fba 100644
--- a/tests/unit/providers/nvidia/test_parameters.py
+++ b/tests/unit/providers/nvidia/test_parameters.py
@@ -8,15 +8,16 @@ import os
 import unittest
 import warnings
 from unittest.mock import patch
-import pytest
 
+import pytest
 from llama_stack_client.types.algorithm_config_param import LoraFinetuningConfig
 from llama_stack_client.types.post_training_supervised_fine_tune_params import (
     TrainingConfig,
     TrainingConfigDataConfig,
-    TrainingConfigOptimizerConfig,
     TrainingConfigEfficiencyConfig,
+    TrainingConfigOptimizerConfig,
 )
+
 from llama_stack.providers.remote.post_training.nvidia.post_training import (
     NvidiaPostTrainingAdapter,
     NvidiaPostTrainingConfig,
diff --git a/tests/unit/providers/nvidia/test_supervised_fine_tuning.py b/tests/unit/providers/nvidia/test_supervised_fine_tuning.py
index 8ef48e05b..7ce89144b 100644
--- a/tests/unit/providers/nvidia/test_supervised_fine_tuning.py
+++ b/tests/unit/providers/nvidia/test_supervised_fine_tuning.py
@@ -6,10 +6,10 @@
 
 import os
 import unittest
-from unittest.mock import patch
 import warnings
-import pytest
+from unittest.mock import patch
 
+import pytest
 from llama_stack_client.types.algorithm_config_param import LoraFinetuningConfig, QatFinetuningConfig
 from llama_stack_client.types.post_training_supervised_fine_tune_params import (
     TrainingConfig,
@@ -18,11 +18,11 @@ from llama_stack_client.types.post_training_supervised_fine_tune_params import (
 )
 
 from llama_stack.providers.remote.post_training.nvidia.post_training import (
+    ListNvidiaPostTrainingJobs,
     NvidiaPostTrainingAdapter,
     NvidiaPostTrainingConfig,
-    NvidiaPostTrainingJobStatusResponse,
-    ListNvidiaPostTrainingJobs,
     NvidiaPostTrainingJob,
+    NvidiaPostTrainingJobStatusResponse,
 )
 
 

From cfd30d2ad5e88732aeaa034920177fbbdc1fe912 Mon Sep 17 00:00:00 2001
From: Xi Yan 
Date: Wed, 26 Mar 2025 22:00:43 -0700
Subject: [PATCH 16/45] fix: update agents test (#1796)

# What does this PR do?
- we no longer query vector db when uploading documents as attachments

[//]: # (If resolving an issue, uncomment and update the line below)
[//]: # (Closes #[issue-number])

## Test Plan
```
pytest --stack-config="http://localhost:8321" -v tests/integration/agents/test_agents.py --text-model meta-llama/Llama-3.3-70B-Instruct
```

```
pytest --stack-config=fireworks -v tests/integration/agents/test_agents.py --text-model meta-llama/Llama-3.3-70B-Instruct --record-responses
```
image


[//]: # (## Documentation)
---
 tests/integration/agents/test_agents.py | 44 ++++++++-----------------
 1 file changed, 13 insertions(+), 31 deletions(-)

diff --git a/tests/integration/agents/test_agents.py b/tests/integration/agents/test_agents.py
index 7011dc02d..2bf9baa80 100644
--- a/tests/integration/agents/test_agents.py
+++ b/tests/integration/agents/test_agents.py
@@ -8,15 +8,13 @@ from typing import Any, Dict
 from uuid import uuid4
 
 import pytest
-from llama_stack_client import Agent, AgentEventLogger, Document
-from llama_stack_client.types.shared_params.agent_config import AgentConfig, ToolConfig
 
 from llama_stack.apis.agents.agents import (
     AgentConfig as Server__AgentConfig,
-)
-from llama_stack.apis.agents.agents import (
     ToolChoice,
 )
+from llama_stack_client import Agent, AgentEventLogger, Document
+from llama_stack_client.types.shared_params.agent_config import AgentConfig, ToolConfig
 
 
 def get_boiling_point(liquid_name: str, celcius: bool = True) -> int:
@@ -173,6 +171,7 @@ def test_tool_config(llama_stack_client_with_mocked_inference, agent_config):
 def test_builtin_tool_web_search(llama_stack_client_with_mocked_inference, agent_config):
     agent_config = {
         **agent_config,
+        "instructions": "You are a helpful assistant that can use web search to answer questions.",
         "tools": [
             "builtin::websearch",
         ],
@@ -184,20 +183,20 @@ def test_builtin_tool_web_search(llama_stack_client_with_mocked_inference, agent
         messages=[
             {
                 "role": "user",
-                "content": "Search the web and tell me who the founder of Meta is.",
+                "content": "Search the web and tell me what is the local time in Tokyo currently.",
             }
         ],
         session_id=session_id,
+        stream=False,
     )
 
-    logs = [str(log) for log in AgentEventLogger().log(response) if log is not None]
-    logs_str = "".join(logs)
-
-    assert "tool_execution>" in logs_str
-    assert "Tool:brave_search Response:" in logs_str
-    assert "mark zuckerberg" in logs_str.lower()
-    if len(agent_config["output_shields"]) > 0:
-        assert "No Violation" in logs_str
+    found_tool_execution = False
+    for step in response.steps:
+        if step.step_type == "tool_execution":
+            assert step.tool_calls[0].tool_name == "brave_search"
+            found_tool_execution = True
+            break
+    assert found_tool_execution
 
 
 def test_builtin_tool_code_execution(llama_stack_client_with_mocked_inference, agent_config):
@@ -427,19 +426,7 @@ def test_rag_agent(llama_stack_client_with_mocked_inference, agent_config, rag_t
             assert expected_kw in response.output_message.content.lower()
 
 
-@pytest.mark.parametrize(
-    "tool",
-    [
-        dict(
-            name="builtin::rag/knowledge_search",
-            args={
-                "vector_db_ids": [],
-            },
-        ),
-        "builtin::rag/knowledge_search",
-    ],
-)
-def test_rag_agent_with_attachments(llama_stack_client_with_mocked_inference, agent_config, tool):
+def test_rag_agent_with_attachments(llama_stack_client_with_mocked_inference, agent_config):
     urls = ["chat.rst", "llama3.rst", "memory_optimizations.rst", "lora_finetune.rst"]
     documents = [
         Document(
@@ -452,7 +439,6 @@ def test_rag_agent_with_attachments(llama_stack_client_with_mocked_inference, ag
     ]
     agent_config = {
         **agent_config,
-        "tools": [tool],
     }
     rag_agent = Agent(llama_stack_client_with_mocked_inference, **agent_config)
     session_id = rag_agent.create_session(f"test-session-{uuid4()}")
@@ -486,10 +472,6 @@ def test_rag_agent_with_attachments(llama_stack_client_with_mocked_inference, ag
             stream=False,
         )
 
-    # rag is called
-    tool_execution_step = [step for step in response.steps if step.step_type == "tool_execution"]
-    assert len(tool_execution_step) >= 1
-    assert tool_execution_step[0].tool_calls[0].tool_name == "knowledge_search"
     assert "lora" in response.output_message.content.lower()
 
 

From 626313b4c817ae1dd094fa1977769220b7cdec8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Han?= 
Date: Thu, 27 Mar 2025 13:16:00 +0100
Subject: [PATCH 17/45] fix: resolve precommit error (#1810)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Sébastien Han 
---
 tests/integration/agents/test_agents.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tests/integration/agents/test_agents.py b/tests/integration/agents/test_agents.py
index 2bf9baa80..754c38fd8 100644
--- a/tests/integration/agents/test_agents.py
+++ b/tests/integration/agents/test_agents.py
@@ -8,13 +8,15 @@ from typing import Any, Dict
 from uuid import uuid4
 
 import pytest
+from llama_stack_client import Agent, AgentEventLogger, Document
+from llama_stack_client.types.shared_params.agent_config import AgentConfig, ToolConfig
 
 from llama_stack.apis.agents.agents import (
     AgentConfig as Server__AgentConfig,
+)
+from llama_stack.apis.agents.agents import (
     ToolChoice,
 )
-from llama_stack_client import Agent, AgentEventLogger, Document
-from llama_stack_client.types.shared_params.agent_config import AgentConfig, ToolConfig
 
 
 def get_boiling_point(liquid_name: str, celcius: bool = True) -> int:

From e3578b1c1bffe63f0585d7bc04a8dd9433e4a442 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Han?= 
Date: Thu, 27 Mar 2025 14:03:39 +0100
Subject: [PATCH 18/45] chore: remove distributions dir (#1809)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

# What does this PR do?

Followup on https://github.com/meta-llama/llama-stack/pull/1801. Move
the deps files to llama_stack/templates.

Signed-off-by: Sébastien Han 
---
 MANIFEST.in                                                | 2 +-
 {distributions => llama_stack/templates}/dependencies.json | 0
 scripts/distro_codegen.py                                  | 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename {distributions => llama_stack/templates}/dependencies.json (100%)

diff --git a/MANIFEST.in b/MANIFEST.in
index 572a9ac0a..5aa699e65 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,5 +1,5 @@
 include pyproject.toml
-include distributions/dependencies.json
+include llama_stack/templates/dependencies.json
 include llama_stack/models/llama/llama3/tokenizer.model
 include llama_stack/distribution/*.sh
 include llama_stack/cli/scripts/*.sh
diff --git a/distributions/dependencies.json b/llama_stack/templates/dependencies.json
similarity index 100%
rename from distributions/dependencies.json
rename to llama_stack/templates/dependencies.json
diff --git a/scripts/distro_codegen.py b/scripts/distro_codegen.py
index e19ba8cb9..98faa53a3 100755
--- a/scripts/distro_codegen.py
+++ b/scripts/distro_codegen.py
@@ -117,7 +117,7 @@ def generate_dependencies_file(change_tracker: ChangedPathTracker):
         if name:
             distribution_deps[name] = deps
 
-    deps_file = REPO_ROOT / "distributions" / "dependencies.json"
+    deps_file = REPO_ROOT / "llama_stack" / "templates" / "dependencies.json"
     change_tracker.add_paths(deps_file)
     with open(deps_file, "w") as f:
         f.write(json.dumps(distribution_deps, indent=2) + "\n")

From 9d9ab7e7dd26dc90f7ea5f944dfd24ed95562c4f Mon Sep 17 00:00:00 2001
From: Antonin Stefanutti 
Date: Thu, 27 Mar 2025 15:18:21 +0100
Subject: [PATCH 19/45] chore: Remove style tags from log formatter (#1808)

# What does this PR do?

Set a formatter for log file handler that does not pollute log messages
with color tags.

## Test Plan

Successfully tested with `LLAMA_STACK_LOG_FILE=server.log llama stack
run ...`
---
 llama_stack/log.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llama_stack/log.py b/llama_stack/log.py
index 0ba95d547..3835b74a1 100644
--- a/llama_stack/log.py
+++ b/llama_stack/log.py
@@ -139,7 +139,7 @@ def setup_logging(category_levels: Dict[str, int], log_file: str | None) -> None
         category_levels (Dict[str, int]): A dictionary mapping categories to their log levels.
         log_file (str): Path to a log file to additionally pipe the logs into
     """
-    log_format = "[dim]%(asctime)s %(name)s:%(lineno)d[/] [yellow dim]%(category)s[/]: %(message)s"
+    log_format = "%(asctime)s %(name)s:%(lineno)d %(category)s: %(message)s"
 
     class CategoryFilter(logging.Filter):
         """Ensure category is always present in log records."""

From 935e706b152ed332361240efc615433494f49d8d Mon Sep 17 00:00:00 2001
From: Dmitry Rogozhkin 
Date: Thu, 27 Mar 2025 07:19:51 -0700
Subject: [PATCH 20/45] docs: fix remote-vllm instructions (#1805)

# What does this PR do?

* Fix location of `run.yaml` relative to the cloned llama stack
repository
* Drop `-it` from `docker run` commands as its not needed running
services

## Test Plan

* Verified running the llama stack following updated instruction

CC: @ashwinb

Signed-off-by: Dmitry Rogozhkin 
---
 .../distributions/self_hosted_distro/remote-vllm.md       | 8 +++++---
 llama_stack/templates/remote-vllm/doc_template.md         | 8 +++++---
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/docs/source/distributions/self_hosted_distro/remote-vllm.md b/docs/source/distributions/self_hosted_distro/remote-vllm.md
index a8cac4971..b6e8a8ad4 100644
--- a/docs/source/distributions/self_hosted_distro/remote-vllm.md
+++ b/docs/source/distributions/self_hosted_distro/remote-vllm.md
@@ -98,11 +98,14 @@ export INFERENCE_PORT=8000
 export INFERENCE_MODEL=meta-llama/Llama-3.2-3B-Instruct
 export LLAMA_STACK_PORT=8321
 
+# You need a local checkout of llama-stack to run this, get it using
+# git clone https://github.com/meta-llama/llama-stack.git
+cd /path/to/llama-stack
+
 docker run \
-  -it \
   --pull always \
   -p $LLAMA_STACK_PORT:$LLAMA_STACK_PORT \
-  -v ./run.yaml:/root/my-run.yaml \
+  -v ./llama_stack/templates/remote-vllm/run.yaml:/root/my-run.yaml \
   llamastack/distribution-remote-vllm \
   --yaml-config /root/my-run.yaml \
   --port $LLAMA_STACK_PORT \
@@ -121,7 +124,6 @@ export SAFETY_MODEL=meta-llama/Llama-Guard-3-1B
 cd /path/to/llama-stack
 
 docker run \
-  -it \
   --pull always \
   -p $LLAMA_STACK_PORT:$LLAMA_STACK_PORT \
   -v ~/.llama:/root/.llama \
diff --git a/llama_stack/templates/remote-vllm/doc_template.md b/llama_stack/templates/remote-vllm/doc_template.md
index 4d585bc2d..57c9f116c 100644
--- a/llama_stack/templates/remote-vllm/doc_template.md
+++ b/llama_stack/templates/remote-vllm/doc_template.md
@@ -85,11 +85,14 @@ export INFERENCE_PORT=8000
 export INFERENCE_MODEL=meta-llama/Llama-3.2-3B-Instruct
 export LLAMA_STACK_PORT=8321
 
+# You need a local checkout of llama-stack to run this, get it using
+# git clone https://github.com/meta-llama/llama-stack.git
+cd /path/to/llama-stack
+
 docker run \
-  -it \
   --pull always \
   -p $LLAMA_STACK_PORT:$LLAMA_STACK_PORT \
-  -v ./run.yaml:/root/my-run.yaml \
+  -v ./llama_stack/templates/remote-vllm/run.yaml:/root/my-run.yaml \
   llamastack/distribution-{{ name }} \
   --yaml-config /root/my-run.yaml \
   --port $LLAMA_STACK_PORT \
@@ -108,7 +111,6 @@ export SAFETY_MODEL=meta-llama/Llama-Guard-3-1B
 cd /path/to/llama-stack
 
 docker run \
-  -it \
   --pull always \
   -p $LLAMA_STACK_PORT:$LLAMA_STACK_PORT \
   -v ~/.llama:/root/.llama \

From 81393afb350e14435449eb8568b753534a0eca85 Mon Sep 17 00:00:00 2001
From: Ihar Hrachyshka 
Date: Thu, 27 Mar 2025 13:15:16 -0400
Subject: [PATCH 21/45] chore: require `data` field for all List*Response
 models (#1799)

# What does this PR do?

No violators are currently in-tree. This is just hardening the api specs
for future consistency.

Signed-off-by: Ihar Hrachyshka 
---
 docs/openapi_generator/pyopenapi/utility.py | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/docs/openapi_generator/pyopenapi/utility.py b/docs/openapi_generator/pyopenapi/utility.py
index cb155fed7..47b72001b 100644
--- a/docs/openapi_generator/pyopenapi/utility.py
+++ b/docs/openapi_generator/pyopenapi/utility.py
@@ -146,9 +146,27 @@ def _validate_api_delete_method_returns_none(method) -> str | None:
         return "does not return None"
 
 
+def _validate_list_parameters_contain_data(method) -> str | None:
+    hints = get_type_hints(method)
+
+    if 'return' not in hints:
+        return "has no return type annotation"
+
+    return_type = hints['return']
+    if not inspect.isclass(return_type):
+        return
+
+    if not return_type.__name__.startswith('List'):
+        return
+
+    if 'data' not in return_type.model_fields:
+        return "does not have data attribute"
+
+
 _VALIDATORS = {
     "GET": [
         _validate_api_method_return_type,
+        _validate_list_parameters_contain_data,
     ],
     "DELETE": [
         _validate_api_delete_method_returns_none,

From b5c27f77ade87488de8a2b7ea194f5320acb9f0e Mon Sep 17 00:00:00 2001
From: Xi Yan 
Date: Thu, 27 Mar 2025 12:12:14 -0700
Subject: [PATCH 22/45] chore: clean up distro doc (#1804)

# What does this PR do?
- hide distro doc (docker needs to be thoroughly tested).

[//]: # (If resolving an issue, uncomment and update the line below)
[//]: # (Closes #[issue-number])

## Test Plan
- docs

[//]: # (## Documentation)
---
 docs/source/distributions/index.md |  2 --
 docs/source/index.md               |  1 -
 docs/source/playground/index.md    | 28 ----------------------------
 3 files changed, 31 deletions(-)

diff --git a/docs/source/distributions/index.md b/docs/source/distributions/index.md
index 1f766e75e..9be2e9ec5 100644
--- a/docs/source/distributions/index.md
+++ b/docs/source/distributions/index.md
@@ -27,8 +27,6 @@ If you have built a container image and want to deploy it in a Kubernetes cluste
 :hidden:
 
 importing_as_library
-building_distro
 configuration
-selection
 kubernetes_deployment
 ```
diff --git a/docs/source/index.md b/docs/source/index.md
index 12a27bd2b..659f955cb 100644
--- a/docs/source/index.md
+++ b/docs/source/index.md
@@ -93,7 +93,6 @@ getting_started/index
 concepts/index
 providers/index
 distributions/index
-distributions/selection
 building_applications/index
 playground/index
 contributing/index
diff --git a/docs/source/playground/index.md b/docs/source/playground/index.md
index 2940ff988..9691609ab 100644
--- a/docs/source/playground/index.md
+++ b/docs/source/playground/index.md
@@ -92,8 +92,6 @@ Interactive pages for users to play with and explore Llama Stack API capabilitie
 
 ## Starting the Llama Stack Playground
 
-### Llama CLI
-
 To start the Llama Stack Playground, run the following commands:
 
 1. Start up the Llama Stack API server
@@ -109,29 +107,3 @@ cd llama_stack/distribution/ui
 pip install -r requirements.txt
 streamlit run app.py
 ```
-
-### Docker
-
-Playground can also be started in a docker image:
-
-```sh
-export LLAMA_STACK_URL=http://localhost:11434
-
-docker run \
-  --pull always \
-  -p 8501:8501 \
-  -e LLAMA_STACK_ENDPOINT=$LLAMA_STACK_URL \
-  quay.io/jland/llama-stack-playground
-```
-
-## Configurable Environment Variables
-
-## Environment Variables
-
-| Environment Variable       | Description                        | Default Value             |
-|----------------------------|------------------------------------|---------------------------|
-| LLAMA_STACK_ENDPOINT       | The endpoint for the Llama Stack   | http://localhost:8321     |
-| FIREWORKS_API_KEY          | API key for Fireworks provider     | (empty string)            |
-| TOGETHER_API_KEY           | API key for Together provider      | (empty string)            |
-| SAMBANOVA_API_KEY          | API key for SambaNova provider     | (empty string)            |
-| OPENAI_API_KEY             | API key for OpenAI provider        | (empty string)            |

From 18bac27d4ed15fa660cdf0e75c5b3712742c2289 Mon Sep 17 00:00:00 2001
From: Ihar Hrachyshka 
Date: Thu, 27 Mar 2025 17:13:22 -0400
Subject: [PATCH 23/45] fix: Use CONDA_DEFAULT_ENV presence as a flag to use
 conda mode (#1555)

# What does this PR do?

This is the second attempt to switch to system packages by default. Now
with a hack to detect conda environment - in which case conda image-type
is used.

Note: Conda will only be used when --image-name is unset *and*
CONDA_DEFAULT_ENV is set. This means that users without conda will
correctly fall back to using system packages when no --image-* arguments
are passed at all.

[//]: # (If resolving an issue, uncomment and update the line below)
[//]: # (Closes #[issue-number])

## Test Plan

Uses virtualenv:

```
$ llama stack build --template ollama --image-type venv
$ llama stack run --image-type venv ~/.llama/distributions/ollama/ollama-run.yaml
[...]
Using virtual environment: /home/ec2-user/src/llama-stack/schedule/.local
[...]
```

Uses system packages (virtualenv already initialized):

```
$ llama stack run ~/.llama/distributions/ollama/ollama-run.yaml
[...]
INFO     2025-03-27 20:46:22,882 llama_stack.cli.stack.run:142 server: No image type or image name provided. Assuming environment packages.
[...]
```

Attempt to run from environment packages without necessary packages
installed:
```
$ python -m venv barebones
$ . ./barebones/bin/activate
$ pip install -e . # to install llama command
$ llama stack run ~/.llama/distributions/ollama/ollama-run.yaml
[...]
ModuleNotFoundError: No module named 'fastapi'
```

^ failed as expected because the environment doesn't have necessary
packages installed.

Now install some packages in the new environment:

```
$ pip install fastapi opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp aiosqlite ollama openai datasets faiss-cpu mcp autoevals
$ llama stack run ~/.llama/distributions/ollama/ollama-run.yaml
[...]
Uvicorn running on http://['::', '0.0.0.0']:8321 (Press CTRL+C to quit)
```

Now see if setting CONDA_DEFAULT_ENV will change what happens by
default:

```
$ export CONDA_DEFAULT_ENV=base
$ llama stack run ~/.llama/distributions/ollama/ollama-run.yaml
[...]
Using conda environment: base
Conda environment base does not exist.
[...]
```

---------

Signed-off-by: Ihar Hrachyshka 
---
 docs/source/distributions/building_distro.md |  2 +-
 llama_stack/cli/stack/_build.py              | 17 ++---
 llama_stack/cli/stack/build.py               |  9 +--
 llama_stack/cli/stack/run.py                 | 74 +++++++++++++++-----
 llama_stack/cli/stack/utils.py               |  8 +++
 llama_stack/distribution/server/server.py    | 28 ++++++--
 6 files changed, 102 insertions(+), 36 deletions(-)

diff --git a/docs/source/distributions/building_distro.md b/docs/source/distributions/building_distro.md
index 9b8c1b9ad..e1e38d7ce 100644
--- a/docs/source/distributions/building_distro.md
+++ b/docs/source/distributions/building_distro.md
@@ -67,7 +67,7 @@ options:
                         Image Type to use for the build. This can be either conda or container or venv. If not specified, will use the image type from the template config. (default:
                         conda)
   --image-name IMAGE_NAME
-                        [for image-type=conda|venv] Name of the conda or virtual environment to use for the build. If not specified, currently active Conda environment will be used if
+                        [for image-type=conda|container|venv] Name of the conda or virtual environment to use for the build. If not specified, currently active Conda environment will be used if
                         found. (default: None)
   --print-deps-only     Print the dependencies for the stack only, without building the stack (default: False)
   --run                 Run the stack after building using the same image type, name, and other applicable arguments (default: False)
diff --git a/llama_stack/cli/stack/_build.py b/llama_stack/cli/stack/_build.py
index d87e3bd0b..e440799d1 100644
--- a/llama_stack/cli/stack/_build.py
+++ b/llama_stack/cli/stack/_build.py
@@ -21,6 +21,7 @@ from prompt_toolkit.completion import WordCompleter
 from prompt_toolkit.validation import Validator
 from termcolor import cprint
 
+from llama_stack.cli.stack.utils import ImageType
 from llama_stack.cli.table import print_table
 from llama_stack.distribution.build import (
     SERVER_DEPENDENCIES,
@@ -62,10 +63,10 @@ def run_stack_build_command(args: argparse.Namespace) -> None:
     if args.list_templates:
         return _run_template_list_cmd()
 
-    if args.image_type == "venv":
+    if args.image_type == ImageType.VENV.value:
         current_venv = os.environ.get("VIRTUAL_ENV")
         image_name = args.image_name or current_venv
-    elif args.image_type == "conda":
+    elif args.image_type == ImageType.CONDA.value:
         current_conda_env = os.environ.get("CONDA_DEFAULT_ENV")
         image_name = args.image_name or current_conda_env
     else:
@@ -84,7 +85,7 @@ def run_stack_build_command(args: argparse.Namespace) -> None:
             build_config.image_type = args.image_type
         else:
             cprint(
-                f"Please specify a image-type (container | conda | venv) for {args.template}",
+                f"Please specify a image-type ({' | '.join(e.value for e in ImageType)}) for {args.template}",
                 color="red",
             )
             sys.exit(1)
@@ -98,15 +99,15 @@ def run_stack_build_command(args: argparse.Namespace) -> None:
         )
 
         image_type = prompt(
-            "> Enter the image type you want your Llama Stack to be built as (container or conda or venv): ",
+            f"> Enter the image type you want your Llama Stack to be built as ({' or '.join(e.value for e in ImageType)}): ",
             validator=Validator.from_callable(
-                lambda x: x in ["container", "conda", "venv"],
-                error_message="Invalid image type, please enter conda or container or venv",
+                lambda x: x in [e.value for e in ImageType],
+                error_message=f"Invalid image type, please enter {' or '.join(e.value for e in ImageType)}",
             ),
-            default="conda",
+            default=ImageType.CONDA.value,
         )
 
-        if image_type == "conda":
+        if image_type == ImageType.CONDA.value:
             if not image_name:
                 cprint(
                     f"No current conda environment detected or specified, will create a new conda environment with the name `llamastack-{name}`",
diff --git a/llama_stack/cli/stack/build.py b/llama_stack/cli/stack/build.py
index 70d74c620..0ada7c615 100644
--- a/llama_stack/cli/stack/build.py
+++ b/llama_stack/cli/stack/build.py
@@ -6,6 +6,7 @@
 import argparse
 import textwrap
 
+from llama_stack.cli.stack.utils import ImageType
 from llama_stack.cli.subcommand import Subcommand
 
 
@@ -46,16 +47,16 @@ class StackBuild(Subcommand):
         self.parser.add_argument(
             "--image-type",
             type=str,
-            help="Image Type to use for the build. This can be either conda or container or venv. If not specified, will use the image type from the template config.",
-            choices=["conda", "container", "venv"],
-            default="conda",
+            help="Image Type to use for the build. If not specified, will use the image type from the template config.",
+            choices=[e.value for e in ImageType],
+            default=ImageType.CONDA.value,
         )
 
         self.parser.add_argument(
             "--image-name",
             type=str,
             help=textwrap.dedent(
-                """[for image-type=conda|venv] Name of the conda or virtual environment to use for
+                f"""[for image-type={"|".join(e.value for e in ImageType)}] Name of the conda or virtual environment to use for
 the build. If not specified, currently active Conda environment will be used if found.
             """
             ),
diff --git a/llama_stack/cli/stack/run.py b/llama_stack/cli/stack/run.py
index 88c3b061a..92015187b 100644
--- a/llama_stack/cli/stack/run.py
+++ b/llama_stack/cli/stack/run.py
@@ -8,6 +8,7 @@ import argparse
 import os
 from pathlib import Path
 
+from llama_stack.cli.stack.utils import ImageType
 from llama_stack.cli.subcommand import Subcommand
 from llama_stack.log import get_logger
 
@@ -43,7 +44,7 @@ class StackRun(Subcommand):
         self.parser.add_argument(
             "--image-name",
             type=str,
-            default=None,
+            default=os.environ.get("CONDA_DEFAULT_ENV"),
             help="Name of the image to run. Defaults to the current conda environment",
         )
         self.parser.add_argument(
@@ -56,7 +57,6 @@ class StackRun(Subcommand):
             "--env",
             action="append",
             help="Environment variables to pass to the server in KEY=VALUE format. Can be specified multiple times.",
-            default=[],
             metavar="KEY=VALUE",
         )
         self.parser.add_argument(
@@ -73,10 +73,24 @@ class StackRun(Subcommand):
             "--image-type",
             type=str,
             help="Image Type used during the build. This can be either conda or container or venv.",
-            choices=["conda", "container", "venv"],
-            default="conda",
+            choices=[e.value for e in ImageType],
         )
 
+    # If neither image type nor image name is provided, but at the same time
+    # the current environment has conda breadcrumbs, then assume what the user
+    # wants to use conda mode and not the usual default mode (using
+    # pre-installed system packages).
+    #
+    # Note: yes, this is hacky. It's implemented this way to keep the existing
+    # conda users unaffected by the switch of the default behavior to using
+    # system packages.
+    def _get_image_type_and_name(self, args: argparse.Namespace) -> tuple[str, str]:
+        conda_env = os.environ.get("CONDA_DEFAULT_ENV")
+        if conda_env and args.image_name == conda_env:
+            logger.warning(f"Conda detected. Using conda environment {conda_env} for the run.")
+            return ImageType.CONDA.value, args.image_name
+        return args.image_type, args.image_name
+
     def _run_stack_run_cmd(self, args: argparse.Namespace) -> None:
         import yaml
 
@@ -120,20 +134,44 @@ class StackRun(Subcommand):
         except AttributeError as e:
             self.parser.error(f"failed to parse config file '{config_file}':\n {e}")
 
-        run_args = formulate_run_args(args.image_type, args.image_name, config, template_name)
+        image_type, image_name = self._get_image_type_and_name(args)
 
-        run_args.extend([str(config_file), str(args.port)])
-        if args.disable_ipv6:
-            run_args.append("--disable-ipv6")
+        # If neither image type nor image name is provided, assume the server should be run directly
+        # using the current environment packages.
+        if not image_type and not image_name:
+            logger.info("No image type or image name provided. Assuming environment packages.")
+            from llama_stack.distribution.server.server import main as server_main
 
-        for env_var in args.env:
-            if "=" not in env_var:
-                self.parser.error(f"Environment variable '{env_var}' must be in KEY=VALUE format")
-            key, value = env_var.split("=", 1)  # split on first = only
-            if not key:
-                self.parser.error(f"Environment variable '{env_var}' has empty key")
-            run_args.extend(["--env", f"{key}={value}"])
+            # Build the server args from the current args passed to the CLI
+            server_args = argparse.Namespace()
+            for arg in vars(args):
+                # If this is a function, avoid passing it
+                # "args" contains:
+                # func=>
+                if callable(getattr(args, arg)):
+                    continue
+                setattr(server_args, arg, getattr(args, arg))
 
-        if args.tls_keyfile and args.tls_certfile:
-            run_args.extend(["--tls-keyfile", args.tls_keyfile, "--tls-certfile", args.tls_certfile])
-        run_command(run_args)
+            # Run the server
+            server_main(server_args)
+        else:
+            run_args = formulate_run_args(image_type, image_name, config, template_name)
+
+            run_args.extend([str(config_file), str(args.port)])
+            if args.disable_ipv6:
+                run_args.append("--disable-ipv6")
+
+            if args.env:
+                for env_var in args.env:
+                    if "=" not in env_var:
+                        self.parser.error(f"Environment variable '{env_var}' must be in KEY=VALUE format")
+                        return
+                    key, value = env_var.split("=", 1)  # split on first = only
+                    if not key:
+                        self.parser.error(f"Environment variable '{env_var}' has empty key")
+                        return
+                    run_args.extend(["--env", f"{key}={value}"])
+
+            if args.tls_keyfile and args.tls_certfile:
+                run_args.extend(["--tls-keyfile", args.tls_keyfile, "--tls-certfile", args.tls_certfile])
+            run_command(run_args)
diff --git a/llama_stack/cli/stack/utils.py b/llama_stack/cli/stack/utils.py
index 1e83a5cc8..74a606b2b 100644
--- a/llama_stack/cli/stack/utils.py
+++ b/llama_stack/cli/stack/utils.py
@@ -4,6 +4,14 @@
 # This source code is licensed under the terms described in the LICENSE file in
 # the root directory of this source tree.
 
+from enum import Enum
+
+
+class ImageType(Enum):
+    CONDA = "conda"
+    CONTAINER = "container"
+    VENV = "venv"
+
 
 def print_subcommand_description(parser, subparsers):
     """Print descriptions of subcommands."""
diff --git a/llama_stack/distribution/server/server.py b/llama_stack/distribution/server/server.py
index b967b0269..7d4ec2a2f 100644
--- a/llama_stack/distribution/server/server.py
+++ b/llama_stack/distribution/server/server.py
@@ -15,7 +15,7 @@ import warnings
 from contextlib import asynccontextmanager
 from importlib.metadata import version as parse_version
 from pathlib import Path
-from typing import Any, List, Union
+from typing import Any, List, Optional, Union
 
 import yaml
 from fastapi import Body, FastAPI, HTTPException, Request
@@ -294,11 +294,17 @@ class ClientVersionMiddleware:
         return await self.app(scope, receive, send)
 
 
-def main():
+def main(args: Optional[argparse.Namespace] = None):
     """Start the LlamaStack server."""
     parser = argparse.ArgumentParser(description="Start the LlamaStack server.")
     parser.add_argument(
         "--yaml-config",
+        dest="config",
+        help="(Deprecated) Path to YAML configuration file - use --config instead",
+    )
+    parser.add_argument(
+        "--config",
+        dest="config",
         help="Path to YAML configuration file",
     )
     parser.add_argument(
@@ -328,12 +334,24 @@ def main():
         required="--tls-keyfile" in sys.argv,
     )
 
-    args = parser.parse_args()
+    # Determine whether the server args are being passed by the "run" command, if this is the case
+    # the args will be passed as a Namespace object to the main function, otherwise they will be
+    # parsed from the command line
+    if args is None:
+        args = parser.parse_args()
+
+    # Check for deprecated argument usage
+    if "--yaml-config" in sys.argv:
+        warnings.warn(
+            "The '--yaml-config' argument is deprecated and will be removed in a future version. Use '--config' instead.",
+            DeprecationWarning,
+            stacklevel=2,
+        )
 
     log_line = ""
-    if args.yaml_config:
+    if args.config:
         # if the user provided a config file, use it, even if template was specified
-        config_file = Path(args.yaml_config)
+        config_file = Path(args.config)
         if not config_file.exists():
             raise ValueError(f"Config file {config_file} does not exist")
         log_line = f"Using config file: {config_file}"

From a4f458e1c1e6c83d184b66f5830c0b583a7edc6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Han?= 
Date: Fri, 28 Mar 2025 17:37:42 +0100
Subject: [PATCH 24/45] ci: add myself to CODEOWNERS (#1823)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Sébastien Han 
---
 .github/CODEOWNERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 8097d5f7c..54c01c80d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -2,4 +2,4 @@
 
 # These owners will be the default owners for everything in
 # the repo. Unless a later match takes precedence,
-* @ashwinb @yanxi0830 @hardikjshah @dltn @raghotham @dineshyv @vladimirivic @sixianyi0721 @ehhuang @terrytangyuan @SLR722
+* @ashwinb @yanxi0830 @hardikjshah @dltn @raghotham @dineshyv @vladimirivic @sixianyi0721 @ehhuang @terrytangyuan @SLR722 @leseb

From 37b6da37ba3f62a9267f6242997ee17a4f070b1a Mon Sep 17 00:00:00 2001
From: Francisco Arceo 
Date: Fri, 28 Mar 2025 10:41:33 -0600
Subject: [PATCH 25/45] docs: Document sqlite-vec faiss comparison (#1821)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

# What does this PR do?
This PR documents and benchmarks the performance tradeoffs between
sqlite-vec and FAISS inline VectorDB providers.

# Closes https://github.com/meta-llama/llama-stack/issues/1165

## Test Plan

The test was run using this script:

CLICK TO SHOW SCRIPT 👋 ```python import cProfile import os import uuid import time import random import string import matplotlib.pyplot as plt import pandas as pd from termcolor import cprint from llama_stack_client.types import Document from llama_stack.distribution.library_client import LlamaStackAsLibraryClient from memory_profiler import profile from line_profiler import LineProfiler os.environ["INFERENCE_MODEL"] = "llama3.2:3b-instruct-fp16" os.environ["LLAMA_STACK_CONFIG"] = "ollama" def generate_random_chars(count=400): return ''.join(random.choices(string.ascii_letters, k=count)) def generate_documents(num_docs: int, num_chars: int): documents = [ Document( document_id=f"doc-{i}", content=f"Document content for document {i} - {generate_random_chars(count=num_chars)}", mime_type="text/plain", metadata={}, ) for i in range(num_docs) ] return documents @profile def benchmark_write(client, vector_db_id, documents, batch_size=100): write_times = [] for i in range(0, len(documents), batch_size): batch = documents[i:i + batch_size] start_time = time.time() client.tool_runtime.rag_tool.insert( documents=batch, vector_db_id=vector_db_id, chunk_size_in_tokens=512, ) end_time = time.time() write_times.append(end_time - start_time) return write_times @profile def benchmark_read(client, provider_id, vector_db_id, user_prompts): response_times = [] for prompt in user_prompts: start_time = time.time() response = client.vector_io.query( vector_db_id=vector_db_id, query=prompt, ) end_time = time.time() response_times.append(end_time - start_time) return response_times def profile_functions(): profiler = LineProfiler() profiler.add_function(benchmark_write) profiler.add_function(benchmark_read) return profiler def plot_results(output, batch_size): # Create a DataFrame for easy manipulation df_sqlite = pd.DataFrame(output['sqlite-vec']) df_faiss = pd.DataFrame(output['faiss']) df_sqlite['write_times'] *= 1000 df_faiss['write_times'] *= 1000 avg_write_sqlite = df_sqlite['write_times'].mean() avg_write_faiss = df_faiss['write_times'].mean() avg_read_sqlite = df_sqlite['read_times'].mean() avg_read_faiss = df_faiss['read_times'].mean() plt.figure(figsize=(12, 6)) plt.hist(df_sqlite['write_times'], bins=10, alpha=0.5, color='blue', label='sqlite-vec Write Times') plt.hist(df_faiss['write_times'], bins=10, alpha=0.5, color='red', label='faiss Write Times') plt.axvline(avg_write_sqlite, color='blue', linestyle='--', label=f'Average Write Time (sqlite-vec): {avg_write_sqlite:.3f} ms') plt.axvline(avg_write_faiss, color='red', linestyle='--', label=f'Average Write Time (faiss): {avg_write_faiss:.3f} ms') plt.title(f'Histogram of Write Times for sqlite-vec and faiss\nn = {df_faiss.shape[0]} with batch size = {batch_size}') plt.xlabel('Time (milliseconds)') plt.ylabel('Density') plt.legend() plt.savefig('write_time_comparison.png') plt.close() plt.figure(figsize=(12, 6)) plt.hist(df_sqlite['read_times'], bins=10, alpha=0.5, color='blue', label='sqlite-vec Read Times') plt.hist(df_faiss['read_times'], bins=10, alpha=0.5, color='red', label='faiss Read Times') plt.axvline(avg_read_sqlite, color='blue', linestyle='--', label=f'Average Read Time (sqlite-vec): {avg_read_sqlite:.3f} ms') plt.axvline(avg_read_faiss, color='red', linestyle='--', label=f'Average Read Time (faiss): {avg_read_faiss:.3f} ms') plt.title(f'Histogram of Read Times for sqlite-vec and faiss\nn = {df_faiss.shape[0]}') plt.xlabel('Time (milliseconds)') plt.ylabel('Density') plt.legend() plt.savefig('read_time_comparison.png') plt.close() plt.figure(figsize=(12, 6)) plt.hist(df_sqlite['read_times'], bins=10, alpha=0.5, color='blue', label='sqlite-vec Read Times') plt.hist(df_faiss['read_times'], bins=10, alpha=0.5, color='red', label='faiss Read Times') plt.axvline(avg_read_sqlite, color='blue', linestyle='--', label=f'Average Read Time (sqlite-vec): {avg_read_sqlite:.3f} ms') plt.axvline(avg_read_faiss, color='red', linestyle='--', label=f'Average Read Time (faiss): {avg_read_faiss:.3f} ms') plt.title(f'Histogram of Read Times for sqlite-vec and faiss\nn = {df_faiss.shape[0]}') plt.xlabel('Time (milliseconds)') plt.ylabel('Density') plt.legend() plt.savefig('read_time_comparison.png') plt.close() plt.figure(figsize=(12, 6)) plt.plot(df_sqlite.index, df_sqlite['write_times'], marker='o', markersize=4, linestyle='-', color='blue', label='sqlite-vec Write Times') plt.plot(df_faiss.index, df_faiss['write_times'], marker='x', markersize=4, linestyle='-', color='red', label='faiss Write Times') plt.title(f'Write Times by Operation Sequence\n(batch size = {batch_size})') plt.xlabel('Write Operation Sequence') plt.ylabel('Time (milliseconds)') plt.legend() plt.grid(True, linestyle='--', alpha=0.7) plt.tight_layout() plt.savefig('write_time_sequence.png') plt.close() # Print out the summary table print("\nPerformance Summary for sqlite-vec:") print(df_sqlite) # Print out the summary table print("\nPerformance Summary for faiss:") print(df_faiss) def main(): # Initialize the client client = LlamaStackAsLibraryClient("ollama") vector_db_id = f"test-vector-db-{uuid.uuid4().hex}" _ = client.initialize() # Generate a large dataset num_chars = 50 num_docs = 100 num_writes = 100 write_batch_size = 100 num_reads = 100 documents = generate_documents(num_docs * write_batch_size, num_chars) user_prompts = [ f"Tell me about document {i}" for i in range(1, num_reads + 1) ] providers = ["sqlite-vec", "faiss"] output = { provider_id: {"write_times": None, "read_times": None} for provider_id in providers } # Benchmark writes and reads for SQLite and Faiss for provider_id in providers: cprint(f"Benchmarking provider: {provider_id}", "yellow") client.vector_dbs.register( provider_id=provider_id, vector_db_id=vector_db_id, embedding_model="all-MiniLM-L6-v2", embedding_dimension=384, ) write_times = benchmark_write(client, vector_db_id, documents, write_batch_size) average_write_time_ms = sum(write_times) / len(write_times) * 1000. cprint(f"Average write time for {provider_id} is {average_write_time_ms:.2f} milliseconds for {num_writes} runs", "blue") cprint(f"Benchmarking reads for provider: {provider_id}", "yellow") read_times = benchmark_read(client, provider_id, vector_db_id, user_prompts) average_read_time_ms = sum(read_times) / len(read_times) * 1000. cprint(f"Average read time for {provider_id} is {average_read_time_ms:.2f} milliseconds for {num_reads} runs", "blue") client.vector_dbs.unregister(vector_db_id=vector_db_id) output[provider_id]['write_times'] = write_times output[provider_id]['read_times'] = read_times # Generate plots and summary plot_results(output, write_batch_size) if __name__ == "__main__": cProfile.run('main()', 'profile_output.prof') ```
--------- Signed-off-by: Francisco Javier Arceo --- .../read_time_comparison_sqlite-vec-faiss.png | Bin 0 -> 34038 bytes ...write_time_comparison_sqlite-vec-faiss.png | Bin 0 -> 37760 bytes .../write_time_sequence_sqlite-vec-faiss.png | Bin 0 -> 56902 bytes docs/source/providers/vector_io/sqlite-vec.md | 50 +++++++++++++++++- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 docs/_static/providers/vector_io/read_time_comparison_sqlite-vec-faiss.png create mode 100644 docs/_static/providers/vector_io/write_time_comparison_sqlite-vec-faiss.png create mode 100644 docs/_static/providers/vector_io/write_time_sequence_sqlite-vec-faiss.png diff --git a/docs/_static/providers/vector_io/read_time_comparison_sqlite-vec-faiss.png b/docs/_static/providers/vector_io/read_time_comparison_sqlite-vec-faiss.png new file mode 100644 index 0000000000000000000000000000000000000000..00e5fe03a602f888264317cd57174b7768f1c140 GIT binary patch literal 34038 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 A#{d8T literal 0 HcmV?d00001 diff --git a/docs/_static/providers/vector_io/write_time_comparison_sqlite-vec-faiss.png b/docs/_static/providers/vector_io/write_time_comparison_sqlite-vec-faiss.png new file mode 100644 index 0000000000000000000000000000000000000000..bec7969399d3e2e5a5090dbe79696e94ded4d532 GIT binary patch literal 37760 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 B@TLF& literal 0 HcmV?d00001 diff --git a/docs/_static/providers/vector_io/write_time_sequence_sqlite-vec-faiss.png b/docs/_static/providers/vector_io/write_time_sequence_sqlite-vec-faiss.png new file mode 100644 index 0000000000000000000000000000000000000000..192d5e96ebf5b26f304de393d4557a401199d08b GIT binary patch literal 56902 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�VGS5a6FHZ7|Ei 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 Date: Fri, 28 Mar 2025 13:56:25 -0600 Subject: [PATCH 26/45] fix: Adding chunk_size_in_tokens to playground rag_tool insert (#1826) # What does this PR do? Adding chunk_size_in_tokens to playground rag_tool insert. # Closes #1825 ## Test Plan Tested locally. [//]: # (## Documentation) Signed-off-by: Francisco Javier Arceo --- llama_stack/distribution/ui/page/playground/rag.py | 1 + 1 file changed, 1 insertion(+) diff --git a/llama_stack/distribution/ui/page/playground/rag.py b/llama_stack/distribution/ui/page/playground/rag.py index fded229c4..fcd0f908e 100644 --- a/llama_stack/distribution/ui/page/playground/rag.py +++ b/llama_stack/distribution/ui/page/playground/rag.py @@ -58,6 +58,7 @@ def rag_chat_page(): llama_stack_api.client.tool_runtime.rag_tool.insert( vector_db_id=vector_db_name, # Use the user-provided name documents=documents, + chunk_size_in_tokens=512, ) st.success("Vector database created successfully!") From 7e7bea66ba28a76dcca8480337c6ede7c297623e Mon Sep 17 00:00:00 2001 From: Xi Yan Date: Fri, 28 Mar 2025 12:58:08 -0700 Subject: [PATCH 27/45] fix: skip code interp (#1827) # What does this PR do? - this is a flaky test dependent on model output [//]: # (If resolving an issue, uncomment and update the line below) [//]: # (Closes #[issue-number]) ## Test Plan image [//]: # (## Documentation) --- tests/integration/agents/test_agents.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/integration/agents/test_agents.py b/tests/integration/agents/test_agents.py index 754c38fd8..7aeeb32d8 100644 --- a/tests/integration/agents/test_agents.py +++ b/tests/integration/agents/test_agents.py @@ -520,19 +520,7 @@ def test_rag_and_code_agent(llama_stack_client_with_mocked_inference, agent_conf ], } agent = Agent(llama_stack_client_with_mocked_inference, **agent_config) - inflation_doc = Document( - document_id="test_csv", - content="https://raw.githubusercontent.com/meta-llama/llama-stack-apps/main/examples/resources/inflation.csv", - mime_type="text/csv", - metadata={}, - ) user_prompts = [ - ( - "Here is a csv file, can you describe it?", - [inflation_doc], - "code_interpreter", - "", - ), ( "when was Perplexity the company founded?", [], From e58c7f6c373b1d15a45cb299ccfab24120aaa2df Mon Sep 17 00:00:00 2001 From: ehhuang Date: Fri, 28 Mar 2025 14:40:17 -0700 Subject: [PATCH 28/45] fix(telemetry): root span not yet received (#1828) # What does this PR do? closes #1725 In https://github.com/meta-llama/llama-stack/pull/1759's attempt to make trace_id consistent in llama stack and otel exports, it incorrectly sets the span_id in context, which causes the root span to have a parent ID, leading to the issue in #1725. This PR reverts #1759's change to set the parent context. We will need to follow up with a proper way to do this. ## Test Plan image --- .../inline/telemetry/meta_reference/telemetry.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py index 7e834451d..817085968 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py @@ -202,18 +202,6 @@ class TelemetryAdapter(TelemetryDatasetMixin, Telemetry): parent_span_id = int(event.payload.parent_span_id, 16) parent_span = _GLOBAL_STORAGE["active_spans"].get(parent_span_id) context = trace.set_span_in_context(parent_span) - else: - context = trace.set_span_in_context( - trace.NonRecordingSpan( - trace.SpanContext( - trace_id=int(event.trace_id, 16), - span_id=span_id, - is_remote=False, - trace_flags=trace.TraceFlags(trace.TraceFlags.SAMPLED), - ) - ) - ) - event.attributes["__root_span__"] = "true" span = tracer.start_span( name=event.payload.name, From b7ab1a9710f99db50fad7951ce17002cc27e1192 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 29 Mar 2025 00:18:38 +0000 Subject: [PATCH 29/45] build: Bump version to 0.1.19 --- pyproject.toml | 4 ++-- requirements.txt | 2 +- uv.lock | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c1b6e101b..79e349a9f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "llama_stack" -version = "0.1.8" +version = "0.1.19" authors = [{ name = "Meta Llama", email = "llama-oss@meta.com" }] description = "Llama Stack" readme = "README.md" @@ -27,7 +27,7 @@ dependencies = [ "huggingface-hub", "jinja2>=3.1.6", "jsonschema", - "llama-stack-client>=0.1.8", + "llama-stack-client>=0.1.19", "prompt-toolkit", "python-dotenv", "pydantic>=2", diff --git a/requirements.txt b/requirements.txt index 70e94a525..466a6f2de 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,7 +21,7 @@ idna==3.10 jinja2==3.1.6 jsonschema==4.23.0 jsonschema-specifications==2024.10.1 -llama-stack-client==0.1.8 +llama-stack-client==0.1.19 lxml==5.3.1 markdown-it-py==3.0.0 markupsafe==3.0.2 diff --git a/uv.lock b/uv.lock index b1c95c511..5ea7d9443 100644 --- a/uv.lock +++ b/uv.lock @@ -1316,7 +1316,7 @@ wheels = [ [[package]] name = "llama-stack" -version = "0.1.8" +version = "0.1.19" source = { editable = "." } dependencies = [ { name = "blobfile" }, @@ -1415,7 +1415,7 @@ requires-dist = [ { name = "jinja2", specifier = ">=3.1.6" }, { name = "jinja2", marker = "extra == 'codegen'", specifier = ">=3.1.6" }, { name = "jsonschema" }, - { name = "llama-stack-client", specifier = ">=0.1.8" }, + { name = "llama-stack-client", specifier = ">=0.1.19" }, { name = "mcp", marker = "extra == 'test'" }, { name = "myst-parser", marker = "extra == 'docs'" }, { name = "nbval", marker = "extra == 'dev'" }, @@ -1464,7 +1464,7 @@ provides-extras = ["dev", "unit", "test", "docs", "codegen"] [[package]] name = "llama-stack-client" -version = "0.1.8" +version = "0.1.19" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1481,9 +1481,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/cb/b058f62f52c7a29cc7238866cac357550bfc8ff99afcd1805436ef906181/llama_stack_client-0.1.8.tar.gz", hash = "sha256:2f1ff22c891c4c03e9b8fa18adbc0fb4d6e7337181d90a897760ec368ef3269c", size = 242834 } +sdist = { url = "https://files.pythonhosted.org/packages/3c/e7/5fac23acee430e060cbe12ade872bf17720977755af551a7bd3d5d2e43cd/llama_stack_client-0.1.19.tar.gz", hash = "sha256:061db4584cdbe2606bfe809c6f0caab6637c8e91aa2350ab46e896bc82869e5c", size = 242819 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/aa/d02c314b93be7ce0e447a7d7e3cbbea1955e06651abdf6a273714058e4aa/llama_stack_client-0.1.8-py3-none-any.whl", hash = "sha256:e34e42ff491b3146130f6cf741fd5e901f8cd66302e8608e514655f74cc3df73", size = 274304 }, + { url = "https://files.pythonhosted.org/packages/9c/11/fccdcbae6a0c261172b3384875675e5bbb5ef2612b7ccb96cf2f735ea104/llama_stack_client-0.1.19-py3-none-any.whl", hash = "sha256:7049eeee6ac60947c37495d3f5b77f209d7721d18af9638b6a59a982e97581a6", size = 274309 }, ] [[package]] From daa34909a0a00dab53238e4db4e0e676aeb8c502 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 29 Mar 2025 00:22:35 +0000 Subject: [PATCH 30/45] build: Bump version to 0.1.9 --- pyproject.toml | 4 ++-- uv.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 79e349a9f..d5ca51a48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "llama_stack" -version = "0.1.19" +version = "0.1.9" authors = [{ name = "Meta Llama", email = "llama-oss@meta.com" }] description = "Llama Stack" readme = "README.md" @@ -27,7 +27,7 @@ dependencies = [ "huggingface-hub", "jinja2>=3.1.6", "jsonschema", - "llama-stack-client>=0.1.19", + "llama-stack-client>=0.1.9", "prompt-toolkit", "python-dotenv", "pydantic>=2", diff --git a/uv.lock b/uv.lock index 5ea7d9443..604e9b770 100644 --- a/uv.lock +++ b/uv.lock @@ -1316,7 +1316,7 @@ wheels = [ [[package]] name = "llama-stack" -version = "0.1.19" +version = "0.1.9" source = { editable = "." } dependencies = [ { name = "blobfile" }, @@ -1415,7 +1415,7 @@ requires-dist = [ { name = "jinja2", specifier = ">=3.1.6" }, { name = "jinja2", marker = "extra == 'codegen'", specifier = ">=3.1.6" }, { name = "jsonschema" }, - { name = "llama-stack-client", specifier = ">=0.1.19" }, + { name = "llama-stack-client", specifier = ">=0.1.9" }, { name = "mcp", marker = "extra == 'test'" }, { name = "myst-parser", marker = "extra == 'docs'" }, { name = "nbval", marker = "extra == 'dev'" }, From 74a2584cdb3e013725e516f0d87d2011eaa32fff Mon Sep 17 00:00:00 2001 From: Francisco Arceo Date: Fri, 28 Mar 2025 20:14:07 -0600 Subject: [PATCH 31/45] chore: Updating Milvus Client calls to be non-blocking (#1830) # What does this PR do? This PR converts blocking Milvus Client calls to non-blocking. Another one for https://github.com/meta-llama/llama-stack/issues/1489 ## Test Plan I ran the integration tests from https://github.com/meta-llama/llama-stack/pull/1467 with: ```python pytest -s -v tests/integration/vector_io/test_vector_io.py \ --stack-config inference=sentence-transformers,vector_io=inline::milvus \ --embedding-model all-miniLM-L6-V2 --env MILVUS_DB_PATH=/tmp/moo.db INFO 2025-03-28 21:35:22,726 tests.integration.conftest:41 tests: Setting DISABLE_CODE_SANDBOX=1 for macOS /Users/farceo/dev/llama-stack/.venv/lib/python3.10/site-packages/pytest_asyncio/plugin.py:207: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset. The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session" warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET)) =============================================================================================================================================================================================================================================================== test session starts =============================================================================================================================================================================================================================================================== platform darwin -- Python 3.10.16, pytest-8.3.4, pluggy-1.5.0 -- /Users/farceo/dev/llama-stack/.venv/bin/python3 cachedir: .pytest_cache metadata: {'Python': '3.10.16', 'Platform': 'macOS-15.3.1-arm64-arm-64bit', 'Packages': {'pytest': '8.3.4', 'pluggy': '1.5.0'}, 'Plugins': {'cov': '6.0.0', 'html': '4.1.1', 'metadata': '3.1.1', 'asyncio': '0.25.3', 'anyio': '4.8.0', 'nbval': '0.11.0'}} rootdir: /Users/farceo/dev/llama-stack configfile: pyproject.toml plugins: cov-6.0.0, html-4.1.1, metadata-3.1.1, asyncio-0.25.3, anyio-4.8.0, nbval-0.11.0 asyncio: mode=strict, asyncio_default_fixture_loop_scope=None collected 7 items tests/integration/vector_io/test_vector_io.py::test_vector_db_retrieve[emb=all-miniLM-L6-V2] PASSED tests/integration/vector_io/test_vector_io.py::test_vector_db_register[emb=all-miniLM-L6-V2] PASSED tests/integration/vector_io/test_vector_io.py::test_insert_chunks[emb=all-miniLM-L6-V2-test_case0] PASSED tests/integration/vector_io/test_vector_io.py::test_insert_chunks[emb=all-miniLM-L6-V2-test_case1] PASSED tests/integration/vector_io/test_vector_io.py::test_insert_chunks[emb=all-miniLM-L6-V2-test_case2] PASSED tests/integration/vector_io/test_vector_io.py::test_insert_chunks[emb=all-miniLM-L6-V2-test_case3] PASSED tests/integration/vector_io/test_vector_io.py::test_insert_chunks[emb=all-miniLM-L6-V2-test_case4] PASSED ========================================================================================================================================================================================================================================================= 7 passed, 2 warnings in 40.33s ========================================================================================================================================================================================================================================================== ``` [//]: # (## Documentation) Signed-off-by: Francisco Javier Arceo --- .../providers/remote/vector_io/milvus/milvus.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/llama_stack/providers/remote/vector_io/milvus/milvus.py b/llama_stack/providers/remote/vector_io/milvus/milvus.py index 8ca9212bc..1949d293d 100644 --- a/llama_stack/providers/remote/vector_io/milvus/milvus.py +++ b/llama_stack/providers/remote/vector_io/milvus/milvus.py @@ -4,6 +4,7 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. +import asyncio import hashlib import logging import os @@ -35,15 +36,16 @@ class MilvusIndex(EmbeddingIndex): self.consistency_level = consistency_level async def delete(self): - if self.client.has_collection(self.collection_name): - self.client.drop_collection(collection_name=self.collection_name) + if await asyncio.to_thread(self.client.has_collection, self.collection_name): + await asyncio.to_thread(self.client.drop_collection, collection_name=self.collection_name) async def add_chunks(self, chunks: List[Chunk], embeddings: NDArray): assert len(chunks) == len(embeddings), ( f"Chunk length {len(chunks)} does not match embedding length {len(embeddings)}" ) - if not self.client.has_collection(self.collection_name): - self.client.create_collection( + if not await asyncio.to_thread(self.client.has_collection, self.collection_name): + await asyncio.to_thread( + self.client.create_collection, self.collection_name, dimension=len(embeddings[0]), auto_id=True, @@ -62,7 +64,8 @@ class MilvusIndex(EmbeddingIndex): } ) try: - self.client.insert( + await asyncio.to_thread( + self.client.insert, self.collection_name, data=data, ) @@ -71,7 +74,8 @@ class MilvusIndex(EmbeddingIndex): raise e async def query(self, embedding: NDArray, k: int, score_threshold: float) -> QueryChunksResponse: - search_res = self.client.search( + search_res = await asyncio.to_thread( + self.client.search, collection_name=self.collection_name, data=[embedding], limit=k, From a182705adeff5871229a47ab9ce2fc334708627b Mon Sep 17 00:00:00 2001 From: ehhuang Date: Fri, 28 Mar 2025 20:58:17 -0700 Subject: [PATCH 32/45] fix(telemetry): query_spans (#1831) # What does this PR do? https://github.com/meta-llama/llama-stack/pull/1828 removed __root_span__ attribute which is still needed ## Test Plan added telemetry integration test LLAMA_STACK_CONFIG=http://localhost:5001 pytest -s -v tests/integration/telemetry --safety-shield meta-llama/Llama-Guard-3-8B --text-model accounts/fireworks/models/llama-v3p3-70b-instruct --- .../telemetry/meta_reference/telemetry.py | 2 + tests/integration/telemetry/test_telemetry.py | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 tests/integration/telemetry/test_telemetry.py diff --git a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py index 817085968..168ce5e22 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py @@ -202,6 +202,8 @@ class TelemetryAdapter(TelemetryDatasetMixin, Telemetry): parent_span_id = int(event.payload.parent_span_id, 16) parent_span = _GLOBAL_STORAGE["active_spans"].get(parent_span_id) context = trace.set_span_in_context(parent_span) + else: + event.attributes["__root_span__"] = "true" span = tracer.start_span( name=event.payload.name, diff --git a/tests/integration/telemetry/test_telemetry.py b/tests/integration/telemetry/test_telemetry.py new file mode 100644 index 000000000..10cbb2eeb --- /dev/null +++ b/tests/integration/telemetry/test_telemetry.py @@ -0,0 +1,50 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import time +from uuid import uuid4 + +import pytest +from llama_stack_client import Agent + +from llama_stack.distribution.library_client import LlamaStackAsLibraryClient + + +def test_agent_query_spans(llama_stack_client, text_model_id): + if isinstance(llama_stack_client, LlamaStackAsLibraryClient): + pytest.mark.xfail(reason="Need to fix LlamaStackAsLibraryClient to log spans") + + agent = Agent(llama_stack_client, model=text_model_id, instructions="You are a helpful assistant") + session_id = agent.create_session(f"test-session-{uuid4()}") + agent.create_turn( + messages=[ + { + "role": "user", + "content": "Give me a sentence that contains the word: hello", + } + ], + session_id=session_id, + stream=False, + ) + + # Wait for the span to be logged + time.sleep(2) + + agent_logs = [] + + for span in llama_stack_client.telemetry.query_spans( + attribute_filters=[ + {"key": "session_id", "op": "eq", "value": session_id}, + ], + attributes_to_return=["input", "output"], + ): + print(span.attributes) + if span.attributes["output"] != "no shields": + agent_logs.append(span.attributes) + + assert len(agent_logs) == 1 + assert "Give me a sentence that contains the word: hello" in agent_logs[0]["input"] + assert "hello" in agent_logs[0]["output"].lower() From a4c086cee054a1be1a54b64dd7862897eb2a2cec Mon Sep 17 00:00:00 2001 From: Matthew Farrellee Date: Sat, 29 Mar 2025 11:39:35 -0400 Subject: [PATCH 33/45] fix: skip apis with no providers during `llama stack build` (#1835) # What does this PR do? closes #1834 ## Test Plan `llama stack build` successfully --- llama_stack/cli/stack/_build.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llama_stack/cli/stack/_build.py b/llama_stack/cli/stack/_build.py index e440799d1..ac1933e0e 100644 --- a/llama_stack/cli/stack/_build.py +++ b/llama_stack/cli/stack/_build.py @@ -137,6 +137,8 @@ def run_stack_build_command(args: argparse.Namespace) -> None: providers = dict() for api, providers_for_api in get_provider_registry().items(): available_providers = [x for x in providers_for_api.keys() if x not in ("remote", "remote::sample")] + if not available_providers: + continue api_provider = prompt( "> Enter provider for API {}: ".format(api.value), completer=WordCompleter(available_providers), From d8a8a734b5717dcd0f1919f20b2c80cec74c0565 Mon Sep 17 00:00:00 2001 From: Anamika <44390109+AIMikav@users.noreply.github.com> Date: Sat, 29 Mar 2025 17:09:08 +0000 Subject: [PATCH 34/45] fix: update sink name for traces and metrics in LlamaStack 0.1.8 (#1836) # What does this PR do? This PR updates the sink name configuration for traces and metrics in LlamaStack to align with the latest changes introduced in version 0.1.8. Previously, when using the `otel` sink along with other sinks (like `console` and `sqlite`), the system threw a **ValueError**, with the message: ```shell Value error, 'otel' is not a valid TelemetrySink [type=value_error, input_value='console,otel,sqlite', input_type=str] For further information visit https://errors.pydantic.dev/2.10/v/value_error ``` ## Test Plan - **Test 1:** Ran the LlamaStack server with a configuration containing `console,otel,sqlite` as sinks. - **Expected result:** No errors related to invalid sink names. - **Result:** The system ran without throwing a `ValueError`. - **Test 2:** Verified that the `otel_trace`, `otel_metric` sink now works in combination with other sinks (`console`, `sqlite`). - **Expected result:** Telemetry data is correctly sent to all specified sinks without errors. - **Result:** All telemetry data was successfully sent to the specified sinks. --- docs/source/building_applications/telemetry.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/source/building_applications/telemetry.md b/docs/source/building_applications/telemetry.md index 833117740..4572480cd 100644 --- a/docs/source/building_applications/telemetry.md +++ b/docs/source/building_applications/telemetry.md @@ -45,14 +45,16 @@ Here's an example that sends telemetry signals to all three sink types. Your con - provider_id: meta-reference provider_type: inline::meta-reference config: - sinks: ['console', 'sqlite', 'otel'] - otel_endpoint: "http://localhost:4318/v1/traces" + sinks: ['console', 'sqlite', 'otel_trace', 'otel_metric'] + otel_trace_endpoint: "http://localhost:4318/v1/traces" + otel_metric_endpoint: "http://localhost:4318/v1/metrics" sqlite_db_path: "/path/to/telemetry.db" ``` ### Jaeger to visualize traces -The `otel` sink works with any service compatible with the OpenTelemetry collector. Let's use Jaeger to visualize this data. +The `otel` sink works with any service compatible with the OpenTelemetry collector, traces and metrics has two separate endpoints. +Let's use Jaeger to visualize this data. Start a Jaeger instance with the OTLP HTTP endpoint at 4318 and the Jaeger UI at 16686 using the following command: From 3a2314dcefbc24f3fa5d089d5e566a1af49e4f13 Mon Sep 17 00:00:00 2001 From: ehhuang Date: Sat, 29 Mar 2025 14:55:31 -0700 Subject: [PATCH 35/45] fix(telemetry): library client does not log span (#1833) --- llama_stack/distribution/library_client.py | 3 ++- tests/integration/telemetry/test_telemetry.py | 7 ------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/llama_stack/distribution/library_client.py b/llama_stack/distribution/library_client.py index 565f22ae0..c0143363d 100644 --- a/llama_stack/distribution/library_client.py +++ b/llama_stack/distribution/library_client.py @@ -328,8 +328,9 @@ class AsyncLlamaStackAsLibraryClient(AsyncLlamaStackClient): body = self._convert_body(path, options.method, body) + await start_trace(route, {"__location__": "library_client"}) + async def gen(): - await start_trace(route, {"__location__": "library_client"}) try: async for chunk in await func(**body): data = json.dumps(convert_pydantic_to_json_value(chunk)) diff --git a/tests/integration/telemetry/test_telemetry.py b/tests/integration/telemetry/test_telemetry.py index 10cbb2eeb..c46de3742 100644 --- a/tests/integration/telemetry/test_telemetry.py +++ b/tests/integration/telemetry/test_telemetry.py @@ -7,16 +7,10 @@ import time from uuid import uuid4 -import pytest from llama_stack_client import Agent -from llama_stack.distribution.library_client import LlamaStackAsLibraryClient - def test_agent_query_spans(llama_stack_client, text_model_id): - if isinstance(llama_stack_client, LlamaStackAsLibraryClient): - pytest.mark.xfail(reason="Need to fix LlamaStackAsLibraryClient to log spans") - agent = Agent(llama_stack_client, model=text_model_id, instructions="You are a helpful assistant") session_id = agent.create_session(f"test-session-{uuid4()}") agent.create_turn( @@ -41,7 +35,6 @@ def test_agent_query_spans(llama_stack_client, text_model_id): ], attributes_to_return=["input", "output"], ): - print(span.attributes) if span.attributes["output"] != "no shields": agent_logs.append(span.attributes) From 90efafafb7fffa97f1c8ff3caceac2689a2506a1 Mon Sep 17 00:00:00 2001 From: Xi Yan Date: Sun, 30 Mar 2025 10:33:58 -0700 Subject: [PATCH 36/45] chore: change context to content for agent (#1840) --- .../agents/meta_reference/agent_instance.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/llama_stack/providers/inline/agents/meta_reference/agent_instance.py b/llama_stack/providers/inline/agents/meta_reference/agent_instance.py index 6d85d1a72..b2fc07274 100644 --- a/llama_stack/providers/inline/agents/meta_reference/agent_instance.py +++ b/llama_stack/providers/inline/agents/meta_reference/agent_instance.py @@ -57,11 +57,7 @@ from llama_stack.apis.inference import ( UserMessage, ) from llama_stack.apis.safety import Safety -from llama_stack.apis.tools import ( - ToolGroups, - ToolInvocationResult, - ToolRuntime, -) +from llama_stack.apis.tools import ToolGroups, ToolInvocationResult, ToolRuntime from llama_stack.apis.vector_io import VectorIO from llama_stack.log import get_logger from llama_stack.models.llama.datatypes import ( @@ -459,7 +455,15 @@ class ChatAgent(ShieldRunnerMixin): contexts.append(raw_document_text) attached_context = "\n".join(contexts) - input_messages[-1].context = attached_context + if isinstance(input_messages[-1].content, str): + input_messages[-1].content += attached_context + elif isinstance(input_messages[-1].content, list): + input_messages[-1].content.append(TextContentItem(text=attached_context)) + else: + input_messages[-1].content = [ + input_messages[-1].content, + TextContentItem(text=attached_context), + ] session_info = await self.storage.get_session_info(session_id) # if the session has a memory bank id, let the memory tool use it From 7e51a83eacf8516132446d2770fee7a2a63a09bc Mon Sep 17 00:00:00 2001 From: Yuan Tang Date: Mon, 31 Mar 2025 05:37:42 -0400 Subject: [PATCH 37/45] docs: Add link to integration tests instructions and minor clarification (#1838) # What does this PR do? * Added `--text-model` in example command. * Added link to integration tests instruction and a note on specifying models. This is to avoid confusion when all tests are skipped because no model is provided. Signed-off-by: Yuan Tang --- CONTRIBUTING.md | 6 +++++- tests/integration/README.md | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21591481e..5828250d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -88,7 +88,7 @@ BRAVE_SEARCH_API_KEY= And then use this dotenv file when running client SDK tests via the following: ```bash -uv run --env-file .env -- pytest -v tests/integration/inference/test_text_inference.py +uv run --env-file .env -- pytest -v tests/integration/inference/test_text_inference.py --text-model=meta-llama/Llama-3.1-8B-Instruct ``` ## Pre-commit Hooks @@ -126,6 +126,10 @@ source .venv/bin/activate PYTHON_VERSION=3.13 ./scripts/unit-tests.sh ``` +## Running integration tests + +You can run integration tests following the instructions [here](tests/integration/README.md). + ## Adding a new dependency to the project To add a new dependency to the project, you can use the `uv` command. For example, to add `foo` to the project, you can run: diff --git a/tests/integration/README.md b/tests/integration/README.md index beb234740..609831d74 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -23,8 +23,8 @@ Model parameters can be influenced by the following options: - `--judge-model`: comma-separated list of judge models. - `--embedding-dimension`: output dimensionality of the embedding model to use for testing. Default: 384 -Each of these are comma-separated lists and can be used to generate multiple parameter combinations. - +Each of these are comma-separated lists and can be used to generate multiple parameter combinations. Note that tests will be skipped +if no model is specified. Experimental, under development, options: - `--record-responses`: record new API responses instead of using cached ones From 9b478f37563671c5763e4a548297105ea397f548 Mon Sep 17 00:00:00 2001 From: Francisco Arceo Date: Mon, 31 Mar 2025 09:31:53 -0600 Subject: [PATCH 38/45] docs: Adding darkmode to documentation (#1843) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What does this PR do? docs: Adding darkmode to documentation ## Test Plan Tested locally. Here's the look: ![Screenshot 2025-03-31 at 9 43 05 AM](https://github.com/user-attachments/assets/5989dbc8-ba03-4710-ad8d-6d4b9ac79786) ## Issues Related to https://github.com/meta-llama/llama-stack/issues/1815 Closes https://github.com/meta-llama/llama-stack/issues/1844 Signed-off-by: Francisco Javier Arceo --- docs/source/conf.py | 1 + pyproject.toml | 1 + requirements.txt | 2 +- uv.lock | 24 +++++++++++++++++++----- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index e96e86042..fa91a346c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -37,6 +37,7 @@ author = "Meta" extensions = [ "myst_parser", "sphinx_rtd_theme", + "sphinx_rtd_dark_mode", "sphinx_copybutton", "sphinx_tabs.tabs", "sphinx_design", diff --git a/pyproject.toml b/pyproject.toml index d5ca51a48..1f7073411 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,7 @@ docs = [ "sphinx-autobuild", "myst-parser", "sphinx-rtd-theme", + "sphinx_rtd_dark_mode", "sphinx-copybutton", "sphinx-tabs", "sphinx-design", diff --git a/requirements.txt b/requirements.txt index 466a6f2de..4971068e8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,7 +21,7 @@ idna==3.10 jinja2==3.1.6 jsonschema==4.23.0 jsonschema-specifications==2024.10.1 -llama-stack-client==0.1.19 +llama-stack-client==0.1.9 lxml==5.3.1 markdown-it-py==3.0.0 markupsafe==3.0.2 diff --git a/uv.lock b/uv.lock index 604e9b770..afed997f0 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,4 @@ version = 1 -revision = 1 requires-python = ">=3.10" resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", @@ -1363,6 +1362,7 @@ docs = [ { name = "sphinx-autobuild" }, { name = "sphinx-copybutton" }, { name = "sphinx-design" }, + { name = "sphinx-rtd-dark-mode" }, { name = "sphinx-rtd-theme" }, { name = "sphinx-tabs" }, { name = "sphinxcontrib-mermaid" }, @@ -1445,6 +1445,7 @@ requires-dist = [ { name = "sphinx-autobuild", marker = "extra == 'docs'" }, { name = "sphinx-copybutton", marker = "extra == 'docs'" }, { name = "sphinx-design", marker = "extra == 'docs'" }, + { name = "sphinx-rtd-dark-mode", marker = "extra == 'docs'" }, { name = "sphinx-rtd-theme", marker = "extra == 'docs'" }, { name = "sphinx-tabs", marker = "extra == 'docs'" }, { name = "sphinxcontrib-mermaid", marker = "extra == 'docs'" }, @@ -1460,11 +1461,10 @@ requires-dist = [ { name = "types-setuptools", marker = "extra == 'dev'" }, { name = "uvicorn", marker = "extra == 'dev'" }, ] -provides-extras = ["dev", "unit", "test", "docs", "codegen"] [[package]] name = "llama-stack-client" -version = "0.1.19" +version = "0.1.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1481,9 +1481,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/e7/5fac23acee430e060cbe12ade872bf17720977755af551a7bd3d5d2e43cd/llama_stack_client-0.1.19.tar.gz", hash = "sha256:061db4584cdbe2606bfe809c6f0caab6637c8e91aa2350ab46e896bc82869e5c", size = 242819 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/e8/0007ce2142cb504391f8f7362361f389fd6cc5cd5e438690d17fdec97ada/llama_stack_client-0.1.9.tar.gz", hash = "sha256:7580250aa3b755f072a09ae49e643bfddd353e75104d2c7bbf73ef67c691b111", size = 242827 } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/11/fccdcbae6a0c261172b3384875675e5bbb5ef2612b7ccb96cf2f735ea104/llama_stack_client-0.1.19-py3-none-any.whl", hash = "sha256:7049eeee6ac60947c37495d3f5b77f209d7721d18af9638b6a59a982e97581a6", size = 274309 }, + { url = "https://files.pythonhosted.org/packages/9a/01/6904480da963861e79b05bfd082c814a74865a206e330d704181796d59a0/llama_stack_client-0.1.9-py3-none-any.whl", hash = "sha256:87c3f660dd14585a99897fa47a60c3cacbf75683a378577a28738173a5938b62", size = 274296 }, ] [[package]] @@ -2463,6 +2463,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/61/74/49f5d20c514ccc631b940cc9dfec45dcce418dc84a98463a2e2ebec33904/pycryptodomex-3.21.0-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:52e23a0a6e61691134aa8c8beba89de420602541afaae70f66e16060fdcd677e", size = 2257982 }, { url = "https://files.pythonhosted.org/packages/92/4b/d33ef74e2cc0025a259936661bb53432c5bbbadc561c5f2e023bcd73ce4c/pycryptodomex-3.21.0-cp36-abi3-win32.whl", hash = "sha256:a3d77919e6ff56d89aada1bd009b727b874d464cb0e2e3f00a49f7d2e709d76e", size = 1779052 }, { url = "https://files.pythonhosted.org/packages/5b/be/7c991840af1184009fc86267160948350d1bf875f153c97bb471ad944e40/pycryptodomex-3.21.0-cp36-abi3-win_amd64.whl", hash = "sha256:b0e9765f93fe4890f39875e6c90c96cb341767833cfa767f41b490b506fa9ec0", size = 1816307 }, + { url = "https://files.pythonhosted.org/packages/af/ac/24125ad36778914a36f08d61ba5338cb9159382c638d9761ee19c8de822c/pycryptodomex-3.21.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:feaecdce4e5c0045e7a287de0c4351284391fe170729aa9182f6bd967631b3a8", size = 1694999 }, + { url = "https://files.pythonhosted.org/packages/93/73/be7a54a5903508070e5508925ba94493a1f326cfeecfff750e3eb250ea28/pycryptodomex-3.21.0-pp27-pypy_73-win32.whl", hash = "sha256:365aa5a66d52fd1f9e0530ea97f392c48c409c2f01ff8b9a39c73ed6f527d36c", size = 1769437 }, { url = "https://files.pythonhosted.org/packages/e5/9f/39a6187f3986841fa6a9f35c6fdca5030ef73ff708b45a993813a51d7d10/pycryptodomex-3.21.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3efddfc50ac0ca143364042324046800c126a1d63816d532f2e19e6f2d8c0c31", size = 1619607 }, { url = "https://files.pythonhosted.org/packages/f8/70/60bb08e9e9841b18d4669fb69d84b64ce900aacd7eb0ebebd4c7b9bdecd3/pycryptodomex-3.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df2608682db8279a9ebbaf05a72f62a321433522ed0e499bc486a6889b96bf3", size = 1653571 }, { url = "https://files.pythonhosted.org/packages/c9/6f/191b73509291c5ff0dddec9cc54797b1d73303c12b2e4017b24678e57099/pycryptodomex-3.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5823d03e904ea3e53aebd6799d6b8ec63b7675b5d2f4a4bd5e3adcb512d03b37", size = 1691548 }, @@ -3307,6 +3309,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338 }, ] +[[package]] +name = "sphinx-rtd-dark-mode" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx-rtd-theme" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/7c/bb1c20458f498d907d78a357b246a0ee1a3a94ee5a5ec39378726e646661/sphinx_rtd_dark_mode-1.3.0.tar.gz", hash = "sha256:0272bf3d9ef620921adc67e5634a66969419e744da84ea18830adacfdb160ea8", size = 8627 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/f1/16b919bf5d33b282f13c0c39be687c658a33debb2caf4137a63be4bb21f6/sphinx_rtd_dark_mode-1.3.0-py3-none-any.whl", hash = "sha256:478da69c72a2a2ed7665c1f633cc612039f5801df416fd5f7c4820c2fe08c9c5", size = 10031 }, +] + [[package]] name = "sphinx-rtd-theme" version = "3.0.2" From 60430da48af947f6737bdad84c432ce7a8f6086a Mon Sep 17 00:00:00 2001 From: Francisco Arceo Date: Mon, 31 Mar 2025 14:00:02 -0600 Subject: [PATCH 39/45] docs: Update readme for integration tests (#1846) # What does this PR do? Update README for integration tests Signed-off-by: Francisco Javier Arceo --- tests/integration/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration/README.md b/tests/integration/README.md index 609831d74..92bcf7c51 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -36,7 +36,7 @@ Experimental, under development, options: Run all text inference tests with the `together` distribution: ```bash -pytest -s -v tests/api/inference/test_text_inference.py \ +pytest -s -v tests/integration/inference/test_text_inference.py \ --stack-config=together \ --text-model=meta-llama/Llama-3.1-8B-Instruct ``` @@ -44,7 +44,7 @@ pytest -s -v tests/api/inference/test_text_inference.py \ Run all text inference tests with the `together` distribution and `meta-llama/Llama-3.1-8B-Instruct`: ```bash -pytest -s -v tests/api/inference/test_text_inference.py \ +pytest -s -v tests/integration/inference/test_text_inference.py \ --stack-config=together \ --text-model=meta-llama/Llama-3.1-8B-Instruct ``` @@ -57,7 +57,7 @@ VISION_MODELS=meta-llama/Llama-3.2-11B-Vision-Instruct EMBEDDING_MODELS=all-MiniLM-L6-v2 export TOGETHER_API_KEY= -pytest -s -v tests/api/inference/ \ +pytest -s -v tests/integration/inference/ \ --stack-config=together \ --text-model=$TEXT_MODELS \ --vision-model=$VISION_MODELS \ @@ -69,7 +69,7 @@ Same thing but instead of using the distribution, use an adhoc stack with just o ```bash export FIREWORKS_API_KEY= -pytest -s -v tests/api/inference/ \ +pytest -s -v tests/integration/inference/ \ --stack-config=inference=fireworks \ --text-model=$TEXT_MODELS \ --vision-model=$VISION_MODELS \ @@ -81,7 +81,7 @@ Running Vector IO tests for a number of embedding models: ```bash EMBEDDING_MODELS=all-MiniLM-L6-v2 -pytest -s -v tests/api/vector_io/ \ +pytest -s -v tests/integration/vector_io/ \ --stack-config=inference=sentence-transformers,vector_io=sqlite-vec \ --embedding-model=$EMBEDDING_MODELS ``` From d495922949564d519e3b8c38a2d39c3789b34036 Mon Sep 17 00:00:00 2001 From: Francisco Arceo Date: Mon, 31 Mar 2025 14:08:05 -0600 Subject: [PATCH 40/45] docs: Updated documentation and Sphinx configuration (#1845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What does this PR do? The goal of this PR is to make the pages easier to navigate by surfacing the child pages on the navbar, updating some of the copy, moving some of the files around. Some changes: 1. Clarifying Titles 2. Restructuring "Distributions" more formally in its own page to be consistent with Providers and adding some clarity to the child pages to surface them and make them easier to navigate 3. Updated sphinx config to not collapse navigation by default 4. Updated copyright year to be calculated dynamically 5. Moved `docs/source/distributions/index.md` -> `docs/source/distributions/starting_llama_stack_server.md` Another for https://github.com/meta-llama/llama-stack/issues/1815 ## Test Plan Tested locally and pages build (screen shots for example). ## Documentation ### Before: ![Screenshot 2025-03-31 at 1 09 21 PM](https://github.com/user-attachments/assets/98e34f76-f0d9-4055-8e2c-441b1e7d8f6a) ### After: ![Screenshot 2025-03-31 at 1 08 52 PM](https://github.com/user-attachments/assets/dfb6b8ad-3a1d-46b6-8f54-0c553664093f) Signed-off-by: Francisco Javier Arceo --- docs/source/building_applications/index.md | 2 +- docs/source/conf.py | 5 ++- docs/source/distributions/configuration.md | 2 +- .../distributions/importing_as_library.md | 6 ++-- docs/source/distributions/index.md | 32 ++++++------------- .../distributions/kubernetes_deployment.md | 8 ++++- ...{selection.md => list_of_distributions.md} | 2 +- .../starting_llama_stack_server.md | 32 +++++++++++++++++++ docs/source/getting_started/index.md | 5 +-- docs/source/index.md | 7 ++++ 10 files changed, 69 insertions(+), 32 deletions(-) rename docs/source/distributions/{selection.md => list_of_distributions.md} (98%) create mode 100644 docs/source/distributions/starting_llama_stack_server.md diff --git a/docs/source/building_applications/index.md b/docs/source/building_applications/index.md index fa1542676..abe548971 100644 --- a/docs/source/building_applications/index.md +++ b/docs/source/building_applications/index.md @@ -1,4 +1,4 @@ -# Building AI Applications +# Building AI Applications (Examples) Llama Stack provides all the building blocks needed to create sophisticated AI applications. diff --git a/docs/source/conf.py b/docs/source/conf.py index fa91a346c..6099caad7 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,6 +16,7 @@ from docutils import nodes from pathlib import Path import requests import json +from datetime import datetime # Read version from pyproject.toml with Path(__file__).parent.parent.parent.joinpath("pyproject.toml").open("rb") as f: @@ -28,7 +29,7 @@ with Path(__file__).parent.parent.parent.joinpath("pyproject.toml").open("rb") a llama_stack_version_link = f"release notes" project = "llama-stack" -copyright = "2025, Meta" +copyright = f"{datetime.now().year}, Meta" author = "Meta" # -- General configuration --------------------------------------------------- @@ -104,6 +105,8 @@ source_suffix = { # html_theme = "alabaster" html_theme_options = { "canonical_url": "https://github.com/meta-llama/llama-stack", + 'collapse_navigation': False, + # "style_nav_header_background": "#c3c9d4", } diff --git a/docs/source/distributions/configuration.md b/docs/source/distributions/configuration.md index 0f766dcd5..6cd5e161f 100644 --- a/docs/source/distributions/configuration.md +++ b/docs/source/distributions/configuration.md @@ -1,4 +1,4 @@ -# Configuring a Stack +# Configuring a "Stack" The Llama Stack runtime configuration is specified as a YAML file. Here is a simplified version of an example configuration file for the Ollama distribution: diff --git a/docs/source/distributions/importing_as_library.md b/docs/source/distributions/importing_as_library.md index 496574c03..29a5669b3 100644 --- a/docs/source/distributions/importing_as_library.md +++ b/docs/source/distributions/importing_as_library.md @@ -1,10 +1,12 @@ # Using Llama Stack as a Library -If you are planning to use an external service for Inference (even Ollama or TGI counts as external), it is often easier to use Llama Stack as a library. This avoids the overhead of setting up a server. +## Setup Llama Stack without a Server +If you are planning to use an external service for Inference (even Ollama or TGI counts as external), it is often easier to use Llama Stack as a library. +This avoids the overhead of setting up a server. ```bash # setup uv pip install llama-stack -llama stack build --template together --image-type venv +llama stack build --template ollama --image-type venv ``` ```python diff --git a/docs/source/distributions/index.md b/docs/source/distributions/index.md index 9be2e9ec5..103a6131f 100644 --- a/docs/source/distributions/index.md +++ b/docs/source/distributions/index.md @@ -1,32 +1,18 @@ -# Starting a Llama Stack Server +# Distributions Overview -You can run a Llama Stack server in one of the following ways: - -**As a Library**: - -This is the simplest way to get started. Using Llama Stack as a library means you do not need to start a server. This is especially useful when you are not running inference locally and relying on an external inference service (eg. fireworks, together, groq, etc.) See [Using Llama Stack as a Library](importing_as_library) - - -**Container**: - -Another simple way to start interacting with Llama Stack is to just spin up a container (via Docker or Podman) which is pre-built with all the providers you need. We provide a number of pre-built images so you can start a Llama Stack server instantly. You can also build your own custom container. Which distribution to choose depends on the hardware you have. See [Selection of a Distribution](selection) for more details. - - -**Conda**: - -If you have a custom or an advanced setup or you are developing on Llama Stack you can also build a custom Llama Stack server. Using `llama stack build` and `llama stack run` you can build/run a custom Llama Stack server containing the exact combination of providers you wish. We have also provided various templates to make getting started easier. See [Building a Custom Distribution](building_distro) for more details. - - -**Kubernetes**: - -If you have built a container image and want to deploy it in a Kubernetes cluster instead of starting the Llama Stack server locally. See [Kubernetes Deployment Guide](kubernetes_deployment) for more details. +A distribution is a pre-packaged set of Llama Stack components that can be deployed together. +This section provides an overview of the distributions available in Llama Stack. ```{toctree} -:maxdepth: 1 -:hidden: +:maxdepth: 3 importing_as_library configuration +list_of_distributions kubernetes_deployment +building_distro +on_device_distro +remote_hosted_distro +self_hosted_distro ``` diff --git a/docs/source/distributions/kubernetes_deployment.md b/docs/source/distributions/kubernetes_deployment.md index 1b4467934..8ff3f0408 100644 --- a/docs/source/distributions/kubernetes_deployment.md +++ b/docs/source/distributions/kubernetes_deployment.md @@ -1,6 +1,9 @@ # Kubernetes Deployment Guide -Instead of starting the Llama Stack and vLLM servers locally. We can deploy them in a Kubernetes cluster. In this guide, we'll use a local [Kind](https://kind.sigs.k8s.io/) cluster and a vLLM inference service in the same cluster for demonstration purposes. +Instead of starting the Llama Stack and vLLM servers locally. We can deploy them in a Kubernetes cluster. + +### Prerequisites +In this guide, we'll use a local [Kind](https://kind.sigs.k8s.io/) cluster and a vLLM inference service in the same cluster for demonstration purposes. First, create a local Kubernetes cluster via Kind: @@ -33,6 +36,7 @@ data: token: $(HF_TOKEN) ``` + Next, start the vLLM server as a Kubernetes Deployment and Service: ```bash @@ -127,6 +131,7 @@ EOF podman build -f /tmp/test-vllm-llama-stack/Containerfile.llama-stack-run-k8s -t llama-stack-run-k8s /tmp/test-vllm-llama-stack ``` +### Deploying Llama Stack Server in Kubernetes We can then start the Llama Stack server by deploying a Kubernetes Pod and Service: @@ -187,6 +192,7 @@ spec: EOF ``` +### Verifying the Deployment We can check that the LlamaStack server has started: ```bash diff --git a/docs/source/distributions/selection.md b/docs/source/distributions/list_of_distributions.md similarity index 98% rename from docs/source/distributions/selection.md rename to docs/source/distributions/list_of_distributions.md index 269b14bce..5f3616634 100644 --- a/docs/source/distributions/selection.md +++ b/docs/source/distributions/list_of_distributions.md @@ -1,4 +1,4 @@ -# List of Distributions +# Available List of Distributions Here are a list of distributions you can use to start a Llama Stack server that are provided out of the box. diff --git a/docs/source/distributions/starting_llama_stack_server.md b/docs/source/distributions/starting_llama_stack_server.md new file mode 100644 index 000000000..9be2e9ec5 --- /dev/null +++ b/docs/source/distributions/starting_llama_stack_server.md @@ -0,0 +1,32 @@ +# Starting a Llama Stack Server + +You can run a Llama Stack server in one of the following ways: + +**As a Library**: + +This is the simplest way to get started. Using Llama Stack as a library means you do not need to start a server. This is especially useful when you are not running inference locally and relying on an external inference service (eg. fireworks, together, groq, etc.) See [Using Llama Stack as a Library](importing_as_library) + + +**Container**: + +Another simple way to start interacting with Llama Stack is to just spin up a container (via Docker or Podman) which is pre-built with all the providers you need. We provide a number of pre-built images so you can start a Llama Stack server instantly. You can also build your own custom container. Which distribution to choose depends on the hardware you have. See [Selection of a Distribution](selection) for more details. + + +**Conda**: + +If you have a custom or an advanced setup or you are developing on Llama Stack you can also build a custom Llama Stack server. Using `llama stack build` and `llama stack run` you can build/run a custom Llama Stack server containing the exact combination of providers you wish. We have also provided various templates to make getting started easier. See [Building a Custom Distribution](building_distro) for more details. + + +**Kubernetes**: + +If you have built a container image and want to deploy it in a Kubernetes cluster instead of starting the Llama Stack server locally. See [Kubernetes Deployment Guide](kubernetes_deployment) for more details. + + +```{toctree} +:maxdepth: 1 +:hidden: + +importing_as_library +configuration +kubernetes_deployment +``` diff --git a/docs/source/getting_started/index.md b/docs/source/getting_started/index.md index e8ca05d76..13cfd4d2f 100644 --- a/docs/source/getting_started/index.md +++ b/docs/source/getting_started/index.md @@ -1,10 +1,11 @@ # Quick Start -In this guide, we'll walk through how you can use the Llama Stack (server and client SDK) to test a simple RAG agent. +In this guide, we'll walk through how you can use the Llama Stack (server and client SDK) to build a simple [RAG (Retrieval Augmented Generation)](../building_applications/rag.md) agent. A Llama Stack agent is a simple integrated system that can perform tasks by combining a Llama model for reasoning with tools (e.g., RAG, web search, code execution, etc.) for taking actions. In Llama Stack, we provide a server exposing multiple APIs. These APIs are backed by implementations from different providers. For this guide, we will use [Ollama](https://ollama.com/) as the inference provider. +Ollama is an LLM runtime that allows you to run Llama models locally. ### 1. Start Ollama @@ -24,7 +25,7 @@ If you do not have ollama, you can install it from [here](https://ollama.com/dow ### 2. Pick a client environment -Llama Stack has a service-oriented architecture, so every interaction with the Stack happens through an REST interface. You can interact with the Stack in two ways: +Llama Stack has a service-oriented architecture, so every interaction with the Stack happens through a REST interface. You can interact with the Stack in two ways: * Install the `llama-stack-client` PyPI package and point `LlamaStackClient` to a local or remote Llama Stack server. * Or, install the `llama-stack` PyPI package and use the Stack as a library using `LlamaStackAsLibraryClient`. diff --git a/docs/source/index.md b/docs/source/index.md index 659f955cb..22f4ae3fb 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -6,6 +6,7 @@ Llama Stack {{ llama_stack_version }} is now available! See the {{ llama_stack_v # Llama Stack +## What is Llama Stack? Llama Stack defines and standardizes the core building blocks needed to bring generative AI applications to market. It provides a unified set of APIs with implementations from leading service providers, enabling seamless transitions between development and production environments. More specifically, it provides @@ -22,6 +23,12 @@ Llama Stack defines and standardizes the core building blocks needed to bring ge Our goal is to provide pre-packaged implementations (aka "distributions") which can be run in a variety of deployment environments. LlamaStack can assist you in your entire app development lifecycle - start iterating on local, mobile or desktop and seamlessly transition to on-prem or public cloud deployments. At every point in this transition, the same set of APIs and the same developer experience is available. +## How does Llama Stack work? +Llama Stack consists of a [server](./distributions/index.md) (with multiple pluggable API [providers](./providers/index.md)) and [client SDKs](#available-sdks) meant to +be used in your applications. The server can be run in a variety of environments, including local (inline) +development, on-premises, and cloud. The client SDKs are available for Python, Swift, Node, and +Kotlin. + ## Quick Links - New to Llama Stack? Start with the [Introduction](introduction/index) to understand our motivation and vision. From 2ffa2b77ed97c27dde9c2d46a2c4b69bfbb39eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Han?= Date: Mon, 31 Mar 2025 22:08:29 +0200 Subject: [PATCH 41/45] refactor: extract pagination logic into shared helper function (#1770) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What does this PR do? Move pagination logic from LocalFS and HuggingFace implementations into a common helper function to ensure consistent pagination behavior across providers. This reduces code duplication and centralizes pagination logic in one place. ## Test Plan Run this script: ``` from llama_stack_client import LlamaStackClient # Initialize the client client = LlamaStackClient(base_url="http://localhost:8321") # Register a dataset response = client.datasets.register( purpose="eval/messages-answer", # or "eval/question-answer" or "post-training/messages" source={"type": "uri", "uri": "huggingface://datasets/llamastack/simpleqa?split=train"}, dataset_id="my_dataset", # optional, will be auto-generated if not provided metadata={"description": "My evaluation dataset"}, # optional ) # Verify the dataset was registered by listing all datasets datasets = client.datasets.list() print(f"Registered datasets: {[d.identifier for d in datasets]}") # You can then access the data using the datasetio API # rows = client.datasets.iterrows(dataset_id="my_dataset", start_index=1, limit=2) rows = client.datasets.iterrows(dataset_id="my_dataset") print(f"Data: {rows.data}") ``` And play with `start_index` and `limit`. [//]: # (## Documentation) Signed-off-by: Sébastien Han --- docs/_static/llama-stack-spec.html | 21 ++++----- docs/_static/llama-stack-spec.yaml | 34 ++++++++++----- llama_stack/apis/common/responses.py | 23 ++++++++++ llama_stack/apis/datasetio/datasetio.py | 31 ++++++------- llama_stack/distribution/routers/routers.py | 5 ++- .../inline/datasetio/localfs/datasetio.py | 21 +++------ .../datasetio/huggingface/huggingface.py | 21 +++------ .../providers/utils/datasetio/pagination.py | 43 +++++++++++++++++++ uv.lock | 4 +- 9 files changed, 130 insertions(+), 73 deletions(-) create mode 100644 llama_stack/apis/common/responses.py create mode 100644 llama_stack/providers/utils/datasetio/pagination.py diff --git a/docs/_static/llama-stack-spec.html b/docs/_static/llama-stack-spec.html index 4990d845e..1d1b14b4a 100644 --- a/docs/_static/llama-stack-spec.html +++ b/docs/_static/llama-stack-spec.html @@ -2115,7 +2115,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/IterrowsResponse" + "$ref": "#/components/schemas/PaginatedResponse" } } } @@ -2136,7 +2136,7 @@ "tags": [ "DatasetIO" ], - "description": "Get a paginated list of rows from a dataset. Uses cursor-based pagination.", + "description": "Get a paginated list of rows from a dataset.\nUses offset-based pagination where:\n- start_index: The starting index (0-based). If None, starts from beginning.\n- limit: Number of items to return. If None or -1, returns all items.\n\nThe response includes:\n- data: List of items for the current page\n- has_more: Whether there are more items available after this set", "parameters": [ { "name": "dataset_id", @@ -8073,7 +8073,7 @@ "additionalProperties": false, "title": "ToolInvocationResult" }, - "IterrowsResponse": { + "PaginatedResponse": { "type": "object", "properties": { "data": { @@ -8103,19 +8103,20 @@ ] } }, - "description": "The rows in the current page." + "description": "The list of items for the current page" }, - "next_start_index": { - "type": "integer", - "description": "Index into dataset for the first row in the next page. None if there are no more rows." + "has_more": { + "type": "boolean", + "description": "Whether there are more items available after this set" } }, "additionalProperties": false, "required": [ - "data" + "data", + "has_more" ], - "title": "IterrowsResponse", - "description": "A paginated list of rows from a dataset." + "title": "PaginatedResponse", + "description": "A generic paginated response that follows a simple format." }, "Job": { "type": "object", diff --git a/docs/_static/llama-stack-spec.yaml b/docs/_static/llama-stack-spec.yaml index ba3868560..c98e1de89 100644 --- a/docs/_static/llama-stack-spec.yaml +++ b/docs/_static/llama-stack-spec.yaml @@ -1443,7 +1443,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/IterrowsResponse' + $ref: '#/components/schemas/PaginatedResponse' '400': $ref: '#/components/responses/BadRequest400' '429': @@ -1457,7 +1457,20 @@ paths: tags: - DatasetIO description: >- - Get a paginated list of rows from a dataset. Uses cursor-based pagination. + Get a paginated list of rows from a dataset. + + Uses offset-based pagination where: + + - start_index: The starting index (0-based). If None, starts from beginning. + + - limit: Number of items to return. If None or -1, returns all items. + + + The response includes: + + - data: List of items for the current page + + - has_more: Whether there are more items available after this set parameters: - name: dataset_id in: path @@ -5542,7 +5555,7 @@ components: - type: object additionalProperties: false title: ToolInvocationResult - IterrowsResponse: + PaginatedResponse: type: object properties: data: @@ -5557,17 +5570,18 @@ components: - type: string - type: array - type: object - description: The rows in the current page. - next_start_index: - type: integer + description: The list of items for the current page + has_more: + type: boolean description: >- - Index into dataset for the first row in the next page. None if there are - no more rows. + Whether there are more items available after this set additionalProperties: false required: - data - title: IterrowsResponse - description: A paginated list of rows from a dataset. + - has_more + title: PaginatedResponse + description: >- + A generic paginated response that follows a simple format. Job: type: object properties: diff --git a/llama_stack/apis/common/responses.py b/llama_stack/apis/common/responses.py new file mode 100644 index 000000000..f9e9a4c31 --- /dev/null +++ b/llama_stack/apis/common/responses.py @@ -0,0 +1,23 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from typing import Any, Dict, List + +from pydantic import BaseModel + +from llama_stack.schema_utils import json_schema_type + + +@json_schema_type +class PaginatedResponse(BaseModel): + """A generic paginated response that follows a simple format. + + :param data: The list of items for the current page + :param has_more: Whether there are more items available after this set + """ + + data: List[Dict[str, Any]] + has_more: bool diff --git a/llama_stack/apis/datasetio/datasetio.py b/llama_stack/apis/datasetio/datasetio.py index d9d86fe1b..6331882fb 100644 --- a/llama_stack/apis/datasetio/datasetio.py +++ b/llama_stack/apis/datasetio/datasetio.py @@ -6,23 +6,9 @@ from typing import Any, Dict, List, Optional, Protocol, runtime_checkable -from pydantic import BaseModel - +from llama_stack.apis.common.responses import PaginatedResponse from llama_stack.apis.datasets import Dataset -from llama_stack.schema_utils import json_schema_type, webmethod - - -@json_schema_type -class IterrowsResponse(BaseModel): - """ - A paginated list of rows from a dataset. - - :param data: The rows in the current page. - :param next_start_index: Index into dataset for the first row in the next page. None if there are no more rows. - """ - - data: List[Dict[str, Any]] - next_start_index: Optional[int] = None +from llama_stack.schema_utils import webmethod class DatasetStore(Protocol): @@ -34,15 +20,22 @@ class DatasetIO(Protocol): # keeping for aligning with inference/safety, but this is not used dataset_store: DatasetStore - # TODO(xiyan): there's a flakiness here where setting route to "/datasets/" here will not result in proper routing @webmethod(route="/datasetio/iterrows/{dataset_id:path}", method="GET") async def iterrows( self, dataset_id: str, start_index: Optional[int] = None, limit: Optional[int] = None, - ) -> IterrowsResponse: - """Get a paginated list of rows from a dataset. Uses cursor-based pagination. + ) -> PaginatedResponse: + """Get a paginated list of rows from a dataset. + + Uses offset-based pagination where: + - start_index: The starting index (0-based). If None, starts from beginning. + - limit: Number of items to return. If None or -1, returns all items. + + The response includes: + - data: List of items for the current page + - has_more: Whether there are more items available after this set :param dataset_id: The ID of the dataset to get the rows from. :param start_index: Index into dataset for the first row to get. Get all rows if None. diff --git a/llama_stack/distribution/routers/routers.py b/llama_stack/distribution/routers/routers.py index 6ff36a65c..53f21f9d8 100644 --- a/llama_stack/distribution/routers/routers.py +++ b/llama_stack/distribution/routers/routers.py @@ -12,7 +12,8 @@ from llama_stack.apis.common.content_types import ( InterleavedContent, InterleavedContentItem, ) -from llama_stack.apis.datasetio import DatasetIO, IterrowsResponse +from llama_stack.apis.common.responses import PaginatedResponse +from llama_stack.apis.datasetio import DatasetIO from llama_stack.apis.datasets import DatasetPurpose, DataSource from llama_stack.apis.eval import BenchmarkConfig, Eval, EvaluateResponse, Job from llama_stack.apis.inference import ( @@ -497,7 +498,7 @@ class DatasetIORouter(DatasetIO): dataset_id: str, start_index: Optional[int] = None, limit: Optional[int] = None, - ) -> IterrowsResponse: + ) -> PaginatedResponse: logger.debug( f"DatasetIORouter.iterrows: {dataset_id}, {start_index=} {limit=}", ) diff --git a/llama_stack/providers/inline/datasetio/localfs/datasetio.py b/llama_stack/providers/inline/datasetio/localfs/datasetio.py index f489739bf..e71107d61 100644 --- a/llama_stack/providers/inline/datasetio/localfs/datasetio.py +++ b/llama_stack/providers/inline/datasetio/localfs/datasetio.py @@ -7,9 +7,11 @@ from typing import Any, Dict, List, Optional import pandas -from llama_stack.apis.datasetio import DatasetIO, IterrowsResponse +from llama_stack.apis.common.responses import PaginatedResponse +from llama_stack.apis.datasetio import DatasetIO from llama_stack.apis.datasets import Dataset from llama_stack.providers.datatypes import DatasetsProtocolPrivate +from llama_stack.providers.utils.datasetio.pagination import paginate_records from llama_stack.providers.utils.datasetio.url_utils import get_dataframe_from_uri from llama_stack.providers.utils.kvstore import kvstore_impl @@ -92,24 +94,13 @@ class LocalFSDatasetIOImpl(DatasetIO, DatasetsProtocolPrivate): dataset_id: str, start_index: Optional[int] = None, limit: Optional[int] = None, - ) -> IterrowsResponse: + ) -> PaginatedResponse: dataset_def = self.dataset_infos[dataset_id] dataset_impl = PandasDataframeDataset(dataset_def) await dataset_impl.load() - start_index = start_index or 0 - - if limit is None or limit == -1: - end = len(dataset_impl) - else: - end = min(start_index + limit, len(dataset_impl)) - - rows = dataset_impl[start_index:end] - - return IterrowsResponse( - data=rows, - next_start_index=end if end < len(dataset_impl) else None, - ) + records = dataset_impl.df.to_dict("records") + return paginate_records(records, start_index, limit) async def append_rows(self, dataset_id: str, rows: List[Dict[str, Any]]) -> None: dataset_def = self.dataset_infos[dataset_id] diff --git a/llama_stack/providers/remote/datasetio/huggingface/huggingface.py b/llama_stack/providers/remote/datasetio/huggingface/huggingface.py index fe3195332..7a17e5e42 100644 --- a/llama_stack/providers/remote/datasetio/huggingface/huggingface.py +++ b/llama_stack/providers/remote/datasetio/huggingface/huggingface.py @@ -8,9 +8,11 @@ from urllib.parse import parse_qs, urlparse import datasets as hf_datasets -from llama_stack.apis.datasetio import DatasetIO, IterrowsResponse +from llama_stack.apis.common.responses import PaginatedResponse +from llama_stack.apis.datasetio import DatasetIO from llama_stack.apis.datasets import Dataset from llama_stack.providers.datatypes import DatasetsProtocolPrivate +from llama_stack.providers.utils.datasetio.pagination import paginate_records from llama_stack.providers.utils.kvstore import kvstore_impl from .config import HuggingfaceDatasetIOConfig @@ -70,24 +72,13 @@ class HuggingfaceDatasetIOImpl(DatasetIO, DatasetsProtocolPrivate): dataset_id: str, start_index: Optional[int] = None, limit: Optional[int] = None, - ) -> IterrowsResponse: + ) -> PaginatedResponse: dataset_def = self.dataset_infos[dataset_id] path, params = parse_hf_params(dataset_def) loaded_dataset = hf_datasets.load_dataset(path, **params) - start_index = start_index or 0 - - if limit is None or limit == -1: - end = len(loaded_dataset) - else: - end = min(start_index + limit, len(loaded_dataset)) - - rows = [loaded_dataset[i] for i in range(start_index, end)] - - return IterrowsResponse( - data=rows, - next_start_index=end if end < len(loaded_dataset) else None, - ) + records = [loaded_dataset[i] for i in range(len(loaded_dataset))] + return paginate_records(records, start_index, limit) async def append_rows(self, dataset_id: str, rows: List[Dict[str, Any]]) -> None: dataset_def = self.dataset_infos[dataset_id] diff --git a/llama_stack/providers/utils/datasetio/pagination.py b/llama_stack/providers/utils/datasetio/pagination.py new file mode 100644 index 000000000..1b693f8f5 --- /dev/null +++ b/llama_stack/providers/utils/datasetio/pagination.py @@ -0,0 +1,43 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from typing import Any, Dict, List + +from llama_stack.apis.common.responses import PaginatedResponse + + +def paginate_records( + records: List[Dict[str, Any]], + start_index: int | None = None, + limit: int | None = None, +) -> PaginatedResponse: + """Helper function to handle pagination of records consistently across implementations. + Inspired by stripe's pagination: https://docs.stripe.com/api/pagination + + :param records: List of records to paginate + :param start_index: The starting index (0-based). If None, starts from beginning. + :param limit: Number of items to return. If None or -1, returns all items. + :return: PaginatedResponse with the paginated data + """ + # Handle special case for fetching all rows + if limit is None or limit == -1: + return PaginatedResponse( + data=records, + has_more=False, + ) + + # Use offset-based pagination + start_index = start_index or 0 + end_index = min(start_index + limit, len(records)) + page_data = records[start_index:end_index] + + # Calculate if there are more records + has_more = end_index < len(records) + + return PaginatedResponse( + data=page_data, + has_more=has_more, + ) diff --git a/uv.lock b/uv.lock index afed997f0..7b7b34a4c 100644 --- a/uv.lock +++ b/uv.lock @@ -1,4 +1,5 @@ version = 1 +revision = 1 requires-python = ">=3.10" resolution-markers = [ "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", @@ -1461,6 +1462,7 @@ requires-dist = [ { name = "types-setuptools", marker = "extra == 'dev'" }, { name = "uvicorn", marker = "extra == 'dev'" }, ] +provides-extras = ["dev", "unit", "test", "docs", "codegen"] [[package]] name = "llama-stack-client" @@ -2463,8 +2465,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/61/74/49f5d20c514ccc631b940cc9dfec45dcce418dc84a98463a2e2ebec33904/pycryptodomex-3.21.0-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:52e23a0a6e61691134aa8c8beba89de420602541afaae70f66e16060fdcd677e", size = 2257982 }, { url = "https://files.pythonhosted.org/packages/92/4b/d33ef74e2cc0025a259936661bb53432c5bbbadc561c5f2e023bcd73ce4c/pycryptodomex-3.21.0-cp36-abi3-win32.whl", hash = "sha256:a3d77919e6ff56d89aada1bd009b727b874d464cb0e2e3f00a49f7d2e709d76e", size = 1779052 }, { url = "https://files.pythonhosted.org/packages/5b/be/7c991840af1184009fc86267160948350d1bf875f153c97bb471ad944e40/pycryptodomex-3.21.0-cp36-abi3-win_amd64.whl", hash = "sha256:b0e9765f93fe4890f39875e6c90c96cb341767833cfa767f41b490b506fa9ec0", size = 1816307 }, - { url = "https://files.pythonhosted.org/packages/af/ac/24125ad36778914a36f08d61ba5338cb9159382c638d9761ee19c8de822c/pycryptodomex-3.21.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:feaecdce4e5c0045e7a287de0c4351284391fe170729aa9182f6bd967631b3a8", size = 1694999 }, - { url = "https://files.pythonhosted.org/packages/93/73/be7a54a5903508070e5508925ba94493a1f326cfeecfff750e3eb250ea28/pycryptodomex-3.21.0-pp27-pypy_73-win32.whl", hash = "sha256:365aa5a66d52fd1f9e0530ea97f392c48c409c2f01ff8b9a39c73ed6f527d36c", size = 1769437 }, { url = "https://files.pythonhosted.org/packages/e5/9f/39a6187f3986841fa6a9f35c6fdca5030ef73ff708b45a993813a51d7d10/pycryptodomex-3.21.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3efddfc50ac0ca143364042324046800c126a1d63816d532f2e19e6f2d8c0c31", size = 1619607 }, { url = "https://files.pythonhosted.org/packages/f8/70/60bb08e9e9841b18d4669fb69d84b64ce900aacd7eb0ebebd4c7b9bdecd3/pycryptodomex-3.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df2608682db8279a9ebbaf05a72f62a321433522ed0e499bc486a6889b96bf3", size = 1653571 }, { url = "https://files.pythonhosted.org/packages/c9/6f/191b73509291c5ff0dddec9cc54797b1d73303c12b2e4017b24678e57099/pycryptodomex-3.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5823d03e904ea3e53aebd6799d6b8ec63b7675b5d2f4a4bd5e3adcb512d03b37", size = 1691548 }, From b440a1dc4209c07ba53997f38321fd2c3590eea1 Mon Sep 17 00:00:00 2001 From: Ashwin Bharambe Date: Mon, 31 Mar 2025 13:38:47 -0700 Subject: [PATCH 42/45] test: make sure integration tests runs against the server (#1743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the integration tests started the server, but never really used it because `--stack-config=ollama` uses the ollama template and the inline "llama stack as library" client, not the HTTP client. This PR makes sure we test it both ways. We also add agents tests to the mix. ## Test Plan GitHub --------- Signed-off-by: Sébastien Han Co-authored-by: Sébastien Han --- .github/workflows/integration-tests.yml | 17 +++++++++++++++-- .../inference/test_text_inference.py | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 6e7e99ef9..e03c7401c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -25,7 +25,8 @@ jobs: matrix: # Listing tests manually since some of them currently fail # TODO: generate matrix list from tests/integration when fixed - test-type: [inference, datasets, inspect, scoring, post_training, providers] + test-type: [agents, inference, datasets, inspect, scoring, post_training, providers] + client-type: [library, http] fail-fast: false # we want to run all tests regardless of failure steps: @@ -54,6 +55,8 @@ jobs: uv sync --extra dev --extra test uv pip install ollama faiss-cpu # always test against the latest version of the client + # TODO: this is not necessarily a good idea. we need to test against both published and latest + # to find out backwards compatibility issues. uv pip install git+https://github.com/meta-llama/llama-stack-client-python.git@main uv pip install -e . llama stack build --template ollama --image-type venv @@ -74,6 +77,7 @@ jobs: exit 1 - name: Start Llama Stack server in background + if: matrix.client-type == 'http' env: INFERENCE_MODEL: "meta-llama/Llama-3.2-3B-Instruct" run: | @@ -81,6 +85,7 @@ jobs: nohup uv run llama stack run ./llama_stack/templates/ollama/run.yaml --image-type venv > server.log 2>&1 & - name: Wait for Llama Stack server to be ready + if: matrix.client-type == 'http' run: | echo "Waiting for Llama Stack server..." for i in {1..30}; do @@ -98,4 +103,12 @@ jobs: env: INFERENCE_MODEL: "meta-llama/Llama-3.2-3B-Instruct" run: | - uv run pytest -v tests/integration/${{ matrix.test-type }} --stack-config=ollama --text-model="meta-llama/Llama-3.2-3B-Instruct" --embedding-model=all-MiniLM-L6-v2 + if [ "${{ matrix.client-type }}" == "library" ]; then + stack_config="ollama" + else + stack_config="http://localhost:8321" + fi + uv run pytest -v tests/integration/${{ matrix.test-type }} --stack-config=${stack_config} \ + -k "not(builtin_tool or safety_with_image or code_interpreter or test_rag)" \ + --text-model="meta-llama/Llama-3.2-3B-Instruct" \ + --embedding-model=all-MiniLM-L6-v2 diff --git a/tests/integration/inference/test_text_inference.py b/tests/integration/inference/test_text_inference.py index f558254e5..c1eec35f0 100644 --- a/tests/integration/inference/test_text_inference.py +++ b/tests/integration/inference/test_text_inference.py @@ -275,6 +275,7 @@ def test_text_chat_completion_first_token_profiling(client_with_models, text_mod model_id=text_model_id, messages=messages, stream=False, + timeout=120, # Increase timeout to 2 minutes for large conversation history ) message_content = response.completion_message.content.lower().strip() assert len(message_content) > 0 @@ -301,6 +302,7 @@ def test_text_chat_completion_streaming(client_with_models, text_model_id, test_ model_id=text_model_id, messages=[{"role": "user", "content": question}], stream=True, + timeout=120, # Increase timeout to 2 minutes for large conversation history ) streamed_content = [str(chunk.event.delta.text.lower().strip()) for chunk in response] assert len(streamed_content) > 0 From 0a895c70d1d00abbb24b524c5d48104a75493c68 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 1 Apr 2025 03:53:11 -0400 Subject: [PATCH 43/45] fix(api): don't return list for runtime tools (#1686) # What does this PR do? Don't return list for runtime tools. Instead return Response object for pagination and consistency with other APIs. --------- Signed-off-by: Ihar Hrachyshka --- docs/_static/llama-stack-spec.html | 20 +++++++++- docs/_static/llama-stack-spec.yaml | 15 ++++++- docs/openapi_generator/pyopenapi/utility.py | 18 +++++++-- llama_stack/apis/tools/tools.py | 6 ++- llama_stack/distribution/routers/routers.py | 4 +- .../distribution/routers/routing_tables.py | 2 +- .../code_interpreter/code_interpreter.py | 33 +++++++++------- .../inline/tool_runtime/rag/memory.py | 39 ++++++++++--------- .../tool_runtime/bing_search/bing_search.py | 33 +++++++++------- .../tool_runtime/brave_search/brave_search.py | 35 +++++++++-------- .../model_context_protocol.py | 7 ++-- .../tavily_search/tavily_search.py | 33 +++++++++------- .../wolfram_alpha/wolfram_alpha.py | 33 +++++++++------- 13 files changed, 170 insertions(+), 108 deletions(-) diff --git a/docs/_static/llama-stack-spec.html b/docs/_static/llama-stack-spec.html index 1d1b14b4a..567110829 100644 --- a/docs/_static/llama-stack-spec.html +++ b/docs/_static/llama-stack-spec.html @@ -2688,9 +2688,9 @@ "200": { "description": "OK", "content": { - "application/jsonl": { + "application/json": { "schema": { - "$ref": "#/components/schemas/ToolDef" + "$ref": "#/components/schemas/ListToolDefsResponse" } } } @@ -8328,6 +8328,22 @@ ], "title": "ListRoutesResponse" }, + "ListToolDefsResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ToolDef" + } + } + }, + "additionalProperties": false, + "required": [ + "data" + ], + "title": "ListToolDefsResponse" + }, "ListScoringFunctionsResponse": { "type": "object", "properties": { diff --git a/docs/_static/llama-stack-spec.yaml b/docs/_static/llama-stack-spec.yaml index c98e1de89..1dfd17f55 100644 --- a/docs/_static/llama-stack-spec.yaml +++ b/docs/_static/llama-stack-spec.yaml @@ -1855,9 +1855,9 @@ paths: '200': description: OK content: - application/jsonl: + application/json: schema: - $ref: '#/components/schemas/ToolDef' + $ref: '#/components/schemas/ListToolDefsResponse' '400': $ref: '#/components/responses/BadRequest400' '429': @@ -5732,6 +5732,17 @@ components: required: - data title: ListRoutesResponse + ListToolDefsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ToolDef' + additionalProperties: false + required: + - data + title: ListToolDefsResponse ListScoringFunctionsResponse: type: object properties: diff --git a/docs/openapi_generator/pyopenapi/utility.py b/docs/openapi_generator/pyopenapi/utility.py index 47b72001b..db18e8430 100644 --- a/docs/openapi_generator/pyopenapi/utility.py +++ b/docs/openapi_generator/pyopenapi/utility.py @@ -132,7 +132,18 @@ def _validate_api_method_return_type(method) -> str | None: return_type = hints['return'] if is_optional_type(return_type): - return "returns Optional type" + return "returns Optional type where a return value is mandatory" + + +def _validate_api_method_doesnt_return_list(method) -> str | None: + hints = get_type_hints(method) + + if 'return' not in hints: + return "has no return type annotation" + + return_type = hints['return'] + if get_origin(return_type) is list: + return "returns a list where a PaginatedResponse or List*Response object is expected" def _validate_api_delete_method_returns_none(method) -> str | None: @@ -143,7 +154,7 @@ def _validate_api_delete_method_returns_none(method) -> str | None: return_type = hints['return'] if return_type is not None and return_type is not type(None): - return "does not return None" + return "does not return None where None is mandatory" def _validate_list_parameters_contain_data(method) -> str | None: @@ -160,13 +171,14 @@ def _validate_list_parameters_contain_data(method) -> str | None: return if 'data' not in return_type.model_fields: - return "does not have data attribute" + return "does not have a mandatory data attribute containing the list of objects" _VALIDATORS = { "GET": [ _validate_api_method_return_type, _validate_list_parameters_contain_data, + _validate_api_method_doesnt_return_list, ], "DELETE": [ _validate_api_delete_method_returns_none, diff --git a/llama_stack/apis/tools/tools.py b/llama_stack/apis/tools/tools.py index e0744a75e..4ca72f71d 100644 --- a/llama_stack/apis/tools/tools.py +++ b/llama_stack/apis/tools/tools.py @@ -88,6 +88,10 @@ class ListToolsResponse(BaseModel): data: List[Tool] +class ListToolDefsResponse(BaseModel): + data: list[ToolDef] + + @runtime_checkable @trace_protocol class ToolGroups(Protocol): @@ -148,7 +152,7 @@ class ToolRuntime(Protocol): @webmethod(route="/tool-runtime/list-tools", method="GET") async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: ... + ) -> ListToolDefsResponse: ... @webmethod(route="/tool-runtime/invoke", method="POST") async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: diff --git a/llama_stack/distribution/routers/routers.py b/llama_stack/distribution/routers/routers.py index 53f21f9d8..eed96a40a 100644 --- a/llama_stack/distribution/routers/routers.py +++ b/llama_stack/distribution/routers/routers.py @@ -46,11 +46,11 @@ from llama_stack.apis.scoring import ( from llama_stack.apis.shields import Shield from llama_stack.apis.telemetry import MetricEvent, MetricInResponse, Telemetry from llama_stack.apis.tools import ( + ListToolDefsResponse, RAGDocument, RAGQueryConfig, RAGQueryResult, RAGToolRuntime, - ToolDef, ToolRuntime, ) from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO @@ -707,6 +707,6 @@ class ToolRuntimeRouter(ToolRuntime): async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: + ) -> ListToolDefsResponse: logger.debug(f"ToolRuntimeRouter.list_runtime_tools: {tool_group_id}") return await self.routing_table.get_provider_impl(tool_group_id).list_tools(tool_group_id, mcp_endpoint) diff --git a/llama_stack/distribution/routers/routing_tables.py b/llama_stack/distribution/routers/routing_tables.py index d444b03a3..557330df7 100644 --- a/llama_stack/distribution/routers/routing_tables.py +++ b/llama_stack/distribution/routers/routing_tables.py @@ -568,7 +568,7 @@ class ToolGroupsRoutingTable(CommonRoutingTableImpl, ToolGroups): tool_defs = await self.impls_by_provider_id[provider_id].list_runtime_tools(toolgroup_id, mcp_endpoint) tool_host = ToolHost.model_context_protocol if mcp_endpoint else ToolHost.distribution - for tool_def in tool_defs: + for tool_def in tool_defs.data: tools.append( ToolWithACL( identifier=tool_def.name, diff --git a/llama_stack/providers/inline/tool_runtime/code_interpreter/code_interpreter.py b/llama_stack/providers/inline/tool_runtime/code_interpreter/code_interpreter.py index 9610b9b46..10ac2fcc6 100644 --- a/llama_stack/providers/inline/tool_runtime/code_interpreter/code_interpreter.py +++ b/llama_stack/providers/inline/tool_runtime/code_interpreter/code_interpreter.py @@ -9,10 +9,11 @@ import asyncio import logging import os import tempfile -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional from llama_stack.apis.common.content_types import URL from llama_stack.apis.tools import ( + ListToolDefsResponse, Tool, ToolDef, ToolInvocationResult, @@ -46,20 +47,22 @@ class CodeInterpreterToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime): async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: - return [ - ToolDef( - name="code_interpreter", - description="Execute code", - parameters=[ - ToolParameter( - name="code", - description="The code to execute", - parameter_type="string", - ), - ], - ) - ] + ) -> ListToolDefsResponse: + return ListToolDefsResponse( + data=[ + ToolDef( + name="code_interpreter", + description="Execute code", + parameters=[ + ToolParameter( + name="code", + description="The code to execute", + parameter_type="string", + ), + ], + ) + ] + ) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: script = kwargs["code"] diff --git a/llama_stack/providers/inline/tool_runtime/rag/memory.py b/llama_stack/providers/inline/tool_runtime/rag/memory.py index 8dd846c6f..97c53d454 100644 --- a/llama_stack/providers/inline/tool_runtime/rag/memory.py +++ b/llama_stack/providers/inline/tool_runtime/rag/memory.py @@ -20,6 +20,7 @@ from llama_stack.apis.common.content_types import ( ) from llama_stack.apis.inference import Inference from llama_stack.apis.tools import ( + ListToolDefsResponse, RAGDocument, RAGQueryConfig, RAGQueryResult, @@ -162,27 +163,29 @@ class MemoryToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime, RAGToolRuntime): async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: + ) -> ListToolDefsResponse: # Parameters are not listed since these methods are not yet invoked automatically # by the LLM. The method is only implemented so things like /tools can list without # encountering fatals. - return [ - ToolDef( - name="insert_into_memory", - description="Insert documents into memory", - ), - ToolDef( - name="knowledge_search", - description="Search for information in a database.", - parameters=[ - ToolParameter( - name="query", - description="The query to search for. Can be a natural language sentence or keywords.", - parameter_type="string", - ), - ], - ), - ] + return ListToolDefsResponse( + data=[ + ToolDef( + name="insert_into_memory", + description="Insert documents into memory", + ), + ToolDef( + name="knowledge_search", + description="Search for information in a database.", + parameters=[ + ToolParameter( + name="query", + description="The query to search for. Can be a natural language sentence or keywords.", + parameter_type="string", + ), + ], + ), + ] + ) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: vector_db_ids = kwargs.get("vector_db_ids", []) diff --git a/llama_stack/providers/remote/tool_runtime/bing_search/bing_search.py b/llama_stack/providers/remote/tool_runtime/bing_search/bing_search.py index f494a7fbb..b34c9fd9d 100644 --- a/llama_stack/providers/remote/tool_runtime/bing_search/bing_search.py +++ b/llama_stack/providers/remote/tool_runtime/bing_search/bing_search.py @@ -5,12 +5,13 @@ # the root directory of this source tree. import json -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional import httpx from llama_stack.apis.common.content_types import URL from llama_stack.apis.tools import ( + ListToolDefsResponse, Tool, ToolDef, ToolInvocationResult, @@ -50,20 +51,22 @@ class BingSearchToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime, NeedsRequestP async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: - return [ - ToolDef( - name="web_search", - description="Search the web using Bing Search API", - parameters=[ - ToolParameter( - name="query", - description="The query to search for", - parameter_type="string", - ) - ], - ) - ] + ) -> ListToolDefsResponse: + return ListToolDefsResponse( + data=[ + ToolDef( + name="web_search", + description="Search the web using Bing Search API", + parameters=[ + ToolParameter( + name="query", + description="The query to search for", + parameter_type="string", + ) + ], + ) + ] + ) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: api_key = self._get_api_key() diff --git a/llama_stack/providers/remote/tool_runtime/brave_search/brave_search.py b/llama_stack/providers/remote/tool_runtime/brave_search/brave_search.py index 78b47eb56..41f3ce823 100644 --- a/llama_stack/providers/remote/tool_runtime/brave_search/brave_search.py +++ b/llama_stack/providers/remote/tool_runtime/brave_search/brave_search.py @@ -4,12 +4,13 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional import httpx from llama_stack.apis.common.content_types import URL from llama_stack.apis.tools import ( + ListToolDefsResponse, Tool, ToolDef, ToolInvocationResult, @@ -49,21 +50,23 @@ class BraveSearchToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime, NeedsRequest async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: - return [ - ToolDef( - name="web_search", - description="Search the web for information", - parameters=[ - ToolParameter( - name="query", - description="The query to search for", - parameter_type="string", - ) - ], - built_in_type=BuiltinTool.brave_search, - ) - ] + ) -> ListToolDefsResponse: + return ListToolDefsResponse( + data=[ + ToolDef( + name="web_search", + description="Search the web for information", + parameters=[ + ToolParameter( + name="query", + description="The query to search for", + parameter_type="string", + ) + ], + built_in_type=BuiltinTool.brave_search, + ) + ] + ) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: api_key = self._get_api_key() diff --git a/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py b/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py index f7dc376f8..676917225 100644 --- a/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py +++ b/llama_stack/providers/remote/tool_runtime/model_context_protocol/model_context_protocol.py @@ -4,7 +4,7 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional from urllib.parse import urlparse from mcp import ClientSession @@ -12,6 +12,7 @@ from mcp.client.sse import sse_client from llama_stack.apis.common.content_types import URL from llama_stack.apis.tools import ( + ListToolDefsResponse, ToolDef, ToolInvocationResult, ToolParameter, @@ -31,7 +32,7 @@ class ModelContextProtocolToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime): async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: + ) -> ListToolDefsResponse: if mcp_endpoint is None: raise ValueError("mcp_endpoint is required") @@ -60,7 +61,7 @@ class ModelContextProtocolToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime): }, ) ) - return tools + return ListToolDefsResponse(data=tools) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: tool = await self.tool_store.get_tool(tool_name) diff --git a/llama_stack/providers/remote/tool_runtime/tavily_search/tavily_search.py b/llama_stack/providers/remote/tool_runtime/tavily_search/tavily_search.py index 5b23d94d3..719d6be14 100644 --- a/llama_stack/providers/remote/tool_runtime/tavily_search/tavily_search.py +++ b/llama_stack/providers/remote/tool_runtime/tavily_search/tavily_search.py @@ -5,12 +5,13 @@ # the root directory of this source tree. import json -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional import httpx from llama_stack.apis.common.content_types import URL from llama_stack.apis.tools import ( + ListToolDefsResponse, Tool, ToolDef, ToolInvocationResult, @@ -49,20 +50,22 @@ class TavilySearchToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime, NeedsReques async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: - return [ - ToolDef( - name="web_search", - description="Search the web for information", - parameters=[ - ToolParameter( - name="query", - description="The query to search for", - parameter_type="string", - ) - ], - ) - ] + ) -> ListToolDefsResponse: + return ListToolDefsResponse( + data=[ + ToolDef( + name="web_search", + description="Search the web for information", + parameters=[ + ToolParameter( + name="query", + description="The query to search for", + parameter_type="string", + ) + ], + ) + ] + ) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: api_key = self._get_api_key() diff --git a/llama_stack/providers/remote/tool_runtime/wolfram_alpha/wolfram_alpha.py b/llama_stack/providers/remote/tool_runtime/wolfram_alpha/wolfram_alpha.py index 8489fa7d8..b3e0e120c 100644 --- a/llama_stack/providers/remote/tool_runtime/wolfram_alpha/wolfram_alpha.py +++ b/llama_stack/providers/remote/tool_runtime/wolfram_alpha/wolfram_alpha.py @@ -5,12 +5,13 @@ # the root directory of this source tree. import json -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Optional import httpx from llama_stack.apis.common.content_types import URL from llama_stack.apis.tools import ( + ListToolDefsResponse, Tool, ToolDef, ToolInvocationResult, @@ -50,20 +51,22 @@ class WolframAlphaToolRuntimeImpl(ToolsProtocolPrivate, ToolRuntime, NeedsReques async def list_runtime_tools( self, tool_group_id: Optional[str] = None, mcp_endpoint: Optional[URL] = None - ) -> List[ToolDef]: - return [ - ToolDef( - name="wolfram_alpha", - description="Query WolframAlpha for computational knowledge", - parameters=[ - ToolParameter( - name="query", - description="The query to compute", - parameter_type="string", - ) - ], - ) - ] + ) -> ListToolDefsResponse: + return ListToolDefsResponse( + data=[ + ToolDef( + name="wolfram_alpha", + description="Query WolframAlpha for computational knowledge", + parameters=[ + ToolParameter( + name="query", + description="The query to compute", + parameter_type="string", + ) + ], + ) + ] + ) async def invoke_tool(self, tool_name: str, kwargs: Dict[str, Any]) -> ToolInvocationResult: api_key = self._get_api_key() From c169c164b35b4f7730dc97273c7e7350760ca2d7 Mon Sep 17 00:00:00 2001 From: Rashmi Pawar <168514198+raspawar@users.noreply.github.com> Date: Tue, 1 Apr 2025 17:01:29 +0530 Subject: [PATCH 44/45] fix: NVIDIA embedding results in InternalServerError (#1851) Closes #1819 ## Test Plan ```bash pytest -v tests/integration/inference/test_embedding.py --stack-config=http://localhost:5002 --embedding-model=nvidia/llama-3.2-nv-embedqa-1b-v2 =============================================================================== test session starts ================================================================================ platform linux -- Python 3.10.0, pytest-8.3.5, pluggy-1.5.0 -- /home/ubuntu/miniconda/envs/nvidia-1/bin/python cachedir: .pytest_cache rootdir: /home/ubuntu/llama-stack configfile: pyproject.toml plugins: anyio-4.9.0 collected 23 items tests/integration/inference/test_embedding.py::test_embedding_text[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-list[string]] PASSED [ 4%] tests/integration/inference/test_embedding.py::test_embedding_text[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-list[text]] PASSED [ 8%] tests/integration/inference/test_embedding.py::test_embedding_image[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-list[url,base64]] XFAIL (nvidia/llama-3.2-nv-embedqa-1b-v2 doe...) [ 13%] tests/integration/inference/test_embedding.py::test_embedding_image[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-list[url,string,base64,text]] XFAIL (nvidia/llama-3.2-nv-embed...) [ 17%] tests/integration/inference/test_embedding.py::test_embedding_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-long-end] PASSED [ 21%] tests/integration/inference/test_embedding.py::test_embedding_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-long-start] PASSED [ 26%] tests/integration/inference/test_embedding.py::test_embedding_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-short-end] PASSED [ 30%] tests/integration/inference/test_embedding.py::test_embedding_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-short-start] PASSED [ 34%] tests/integration/inference/test_embedding.py::test_embedding_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-long-text-None] PASSED [ 39%] tests/integration/inference/test_embedding.py::test_embedding_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-long-text-none] PASSED [ 43%] tests/integration/inference/test_embedding.py::test_embedding_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-long-str-None] PASSED [ 47%] tests/integration/inference/test_embedding.py::test_embedding_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-long-str-none] PASSED [ 52%] tests/integration/inference/test_embedding.py::test_embedding_output_dimension[emb=nvidia/llama-3.2-nv-embedqa-1b-v2] PASSED [ 56%] tests/integration/inference/test_embedding.py::test_embedding_task_type[emb=nvidia/llama-3.2-nv-embedqa-1b-v2] PASSED [ 60%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-None] PASSED [ 65%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-none] PASSED [ 69%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-end] PASSED [ 73%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-start] PASSED [ 78%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-NONE] PASSED [ 82%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-END] PASSED [ 86%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-START] PASSED [ 91%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-left] PASSED [ 95%] tests/integration/inference/test_embedding.py::test_embedding_text_truncation_error[emb=nvidia/llama-3.2-nv-embedqa-1b-v2-right] PASSED [100%] ===================================================================== 21 passed, 2 xfailed, 1 warning in 7.18s ===================================================================== ``` [//]: # (## Documentation) cc: @dglogo @mattf @sumitb --- llama_stack/providers/remote/inference/nvidia/nvidia.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llama_stack/providers/remote/inference/nvidia/nvidia.py b/llama_stack/providers/remote/inference/nvidia/nvidia.py index 51c8c6a79..5caf19fda 100644 --- a/llama_stack/providers/remote/inference/nvidia/nvidia.py +++ b/llama_stack/providers/remote/inference/nvidia/nvidia.py @@ -205,7 +205,7 @@ class NVIDIAInferenceAdapter(Inference, ModelRegistryHelper): extra_body["input_type"] = task_type_options[task_type] try: - response = await self._client.embeddings.create( + response = await self._get_client(model).embeddings.create( model=model, input=input, extra_body=extra_body, From 19f504e9e267759c489af287049d479176730d27 Mon Sep 17 00:00:00 2001 From: Francisco Arceo Date: Tue, 1 Apr 2025 06:50:04 -0600 Subject: [PATCH 45/45] docs: Updating docs to source from CONTRIBUTING.md (#1850) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What does this PR do? Another for https://github.com/meta-llama/llama-stack/issues/1815 This links the `CONTRIBUTING.md` file directly so that we don't have to maintain two different files. Also I updated the title for RAG under Building AI Applications. ## Changes Look of what the Contributing page looks like, proof it sources directly from the markdown file. ![Screenshot 2025-04-01 at 12 43 51 AM](https://github.com/user-attachments/assets/f7021d29-eec3-44ad-a5b3-55c4480ea9ac) --------- Signed-off-by: Francisco Javier Arceo --- docs/source/building_applications/rag.md | 2 +- docs/source/contributing/index.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/source/building_applications/rag.md b/docs/source/building_applications/rag.md index c3d02d7dc..fd11d824f 100644 --- a/docs/source/building_applications/rag.md +++ b/docs/source/building_applications/rag.md @@ -1,4 +1,4 @@ -## Using Retrieval Augmented Generation (RAG) +## Retrieval Augmented Generation (RAG) RAG enables your applications to reference and recall information from previous interactions or external documents. diff --git a/docs/source/contributing/index.md b/docs/source/contributing/index.md index 8f89ea9f2..8e4f5e867 100644 --- a/docs/source/contributing/index.md +++ b/docs/source/contributing/index.md @@ -1,14 +1,14 @@ -# Contributing to Llama Stack -Start with the [Contributing Guide](https://github.com/meta-llama/llama-stack/blob/main/CONTRIBUTING.md) for some general tips. This section covers a few key topics in more detail. +```{include} ../../../CONTRIBUTING.md +``` + +See the [Adding a New API Provider](new_api_provider.md) which describes how to add new API providers to the Stack. + -- [Adding a New API Provider](new_api_provider.md) describes adding new API providers to the Stack. -- [Testing Llama Stack](testing.md) provides details about the testing framework and how to test providers and distributions. ```{toctree} :maxdepth: 1 :hidden: new_api_provider -testing ```