diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45891ea37..881dda180 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ on: - main - dev - feat/* + - 0.*.* # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -19,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -27,31 +28,27 @@ jobs: with: python-version: ${{ matrix.python-version }} - # - name: Poetry cache - # uses: actions/cache@v3 - # with: - # path: ~/.cache/pypoetry - # key: poetry-cache-${{ runner.os }}-${{ matrix.python-version }}-${{ env.POETRY_VERSION }} - - name: Install Poetry uses: snok/install-poetry@v1 - name: Install Dependencies # TODO: fix errors so that we can run `make dev` instead run: | + # Setup Virtual Environment + python3 -m venv ./.venv + source .venv/bin/activate make full - name: Lint with ruff run: | + source .venv/bin/activate make lint Typing: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] - pydantic-version: ["==1.10.9", ">=2.x"] - openai-version: [">=1.x"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -59,66 +56,67 @@ jobs: with: python-version: ${{ matrix.python-version }} - # - name: Poetry cache - # uses: actions/cache@v3 - # with: - # path: ~/.cache/pypoetry - # key: poetry-cache-${{ runner.os }}-${{ matrix.python-version }}-${{ env.POETRY_VERSION }}-${{ matrix.pydantic-version }} - - name: Install Poetry uses: snok/install-poetry@v1 - name: Install Dependencies # TODO: fix errors so that we can run `make dev` instead run: | + # Setup Virtual Environment + python3 -m venv ./.venv + source .venv/bin/activate make full - poetry run pip install "pydantic${{ matrix.pydantic-version }}" - poetry run pip install "openai${{ matrix.openai-version }}" - name: Static analysis with pyright run: | + source .venv/bin/activate make type Pytests: runs-on: LargeBois strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] # TODO: fix errors so that we can run both `make dev` and `make full` # dependencies: ['dev', 'full'] - dependencies: ["full"] - pydantic-version: ["==1.10.9", ">=2.x"] - openai-version: [">=1.x"] + # dependencies: ["full"] steps: - uses: actions/checkout@v4 - name: Create .guardrailsrc run: | echo 'id="SYSTEM TESTING"' > ~/.guardrailsrc - echo 'no_metrics=false' >> ~/.guardrailsrc + echo 'enable_metrics=false' >> ~/.guardrailsrc - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - # - name: Poetry cache - # uses: actions/cache@v3 - # with: - # path: ~/.cache/pypoetry - # key: poetry-cache-${{ runner.os }}-${{ matrix.python-version }}-${{ env.POETRY_VERSION }}-${{ matrix.pydantic-version }}-${{ matrix.openai-version }} - - name: Install Poetry uses: snok/install-poetry@v1 - name: Install Dependencies run: | - make ${{ matrix.dependencies }} - poetry run pip install "pydantic${{ matrix.pydantic-version }}" - poetry run pip install "openai${{ matrix.openai-version }}" + # Setup Virtual Environment + python3 -m venv ./.venv + source .venv/bin/activate + + make full + if [ "${{ matrix.python-version }}" == "3.12" ]; then + echo "Installing latest langchain-core and langsmith from PyPI" + pip install "langchain-core>=0.2" "langsmith<0.2.0,>=0.1.75" + fi - name: Run Pytests run: | + source .venv/bin/activate + + echo "langchain-core version:" + pip show langchain-core + echo "langsmith version:" + pip show langsmith + make test-cov - name: Upload to codecov.io diff --git a/.github/workflows/examples_check.yml b/.github/workflows/examples_check.yml index a7eab18b0..8805b263f 100644 --- a/.github/workflows/examples_check.yml +++ b/.github/workflows/examples_check.yml @@ -20,6 +20,7 @@ jobs: COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} HUGGINGFACE_API_KEY: ${{ secrets.HUGGINGFACE_API_KEY }} + MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} NLTK_DATA: /tmp/nltk_data steps: - name: Checkout repository diff --git a/.github/workflows/scripts/run_notebooks.sh b/.github/workflows/scripts/run_notebooks.sh index cd854ceb6..51ff78a52 100755 --- a/.github/workflows/scripts/run_notebooks.sh +++ b/.github/workflows/scripts/run_notebooks.sh @@ -11,7 +11,7 @@ cd docs/examples notebook="$1" # Check if the notebook should be processed -invalid_notebooks=("valid_chess_moves.ipynb" "llamaindex-output-parsing.ipynb" "competitors_check.ipynb") +invalid_notebooks=("llamaindex-output-parsing.ipynb" "competitors_check.ipynb" "guardrails_server.ipynb" "valid_chess_moves.ipynb") if [[ ! " ${invalid_notebooks[@]} " =~ " ${notebook} " ]]; then echo "Processing $notebook..." # poetry run jupyter nbconvert --to notebook --execute "$notebook" diff --git a/.gitignore b/.gitignore index 7a0e987d1..6453239ea 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,10 @@ docusaurus/examples-toc.json .python-version static/docs docusaurus/static/docs +*/bin/* +*/etc/* +*/lib/* +*/lib64/* +*/include/* +*/share/* +pyvenv.cfg \ No newline at end of file diff --git a/Makefile b/Makefile index 59f3d0fc5..6fb50b3e2 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,5 @@ MKDOCS_SERVE_ADDR ?= localhost:8000 # Default address for mkdocs serve, format: :, override with `make docs-serve MKDOCS_SERVE_ADDR=:` -# Extract major package versions for OpenAI and Pydantic -OPENAI_VERSION_MAJOR := $(shell poetry run python -c 'import openai; print(openai.__version__.split(".")[0])') -PYDANTIC_VERSION_MAJOR := $(shell poetry run python -c 'import pydantic; print(pydantic.__version__.split(".")[0])') - -# Construct the typing command using only major versions -TYPING_CMD := type-pydantic-v$(PYDANTIC_VERSION_MAJOR)-openai-v$(OPENAI_VERSION_MAJOR) - autoformat: poetry run ruff check guardrails/ tests/ --fix poetry run ruff format guardrails/ tests/ @@ -14,27 +7,7 @@ autoformat: .PHONY: type type: - @make $(TYPING_CMD) - -type-pydantic-v1-openai-v0: - echo '{"reportDeprecated": true, "exclude": ["guardrails/utils/pydantic_utils/v2.py", "guardrails/utils/openai_utils/v1.py"]}' > pyrightconfig.json - poetry run pyright guardrails/ - rm pyrightconfig.json - -type-pydantic-v1-openai-v1: - echo '{"reportDeprecated": true, "exclude": ["guardrails/utils/pydantic_utils/v2.py", "guardrails/utils/openai_utils/v0.py"]}' > pyrightconfig.json - poetry run pyright guardrails/ - rm pyrightconfig.json - -type-pydantic-v2-openai-v0: - echo '{"reportDeprecated": true, "exclude": ["guardrails/utils/pydantic_utils/v1.py", "guardrails/utils/openai_utils/v1.py"]}' > pyrightconfig.json - poetry run pyright guardrails/ - rm pyrightconfig.json - -type-pydantic-v2-openai-v1: - echo '{"reportDeprecated": true, "exclude": ["guardrails/utils/pydantic_utils/v1.py", "guardrails/utils/openai_utils/v0.py"]}' > pyrightconfig.json poetry run pyright guardrails/ - rm pyrightconfig.json lint: poetry run ruff check guardrails/ tests/ @@ -85,3 +58,15 @@ precommit: pyright guardrails/ make lint ./.github/workflows/scripts/update_notebook_matrix.sh + +refresh: + echo "Removing old virtual environment" + rm -rf ./.venv; + echo "Creating new virtual environment" + python3 -m venv ./.venv; + echo "Sourcing and installing" + source ./.venv/bin/activate && make full; + +update-lock: + poetry lock --no-update + diff --git a/docs/.gitignore b/docs/.gitignore index 075b2542a..8cb2c0d53 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1 +1,2 @@ /.quarto/ +lib64 diff --git a/docs/api_reference/async_guard.md b/docs/api_reference/async_guard.md new file mode 100644 index 000000000..f34af71e5 --- /dev/null +++ b/docs/api_reference/async_guard.md @@ -0,0 +1,22 @@ + + + +::: guardrails.guard.AsyncGuard + options: + members: + - "__init__" + - "from_rail" + - "from_rail_string" + - "from_pydantic" + - "from_string" + - "configure" + - "use" + - "use_many" + - "__call__" + - "parse" + - "validate" + - "error_spans_in_output" + - "json_function_calling_tool" + - "to_dict" + - "from_dict" + - "to_runnable" diff --git a/docs/api_reference/data_types.md b/docs/api_reference/data_types.md index cceadf2c6..1cc62daec 100644 --- a/docs/api_reference/data_types.md +++ b/docs/api_reference/data_types.md @@ -3,16 +3,5 @@ ::: guardrails.datatypes options: filters: - - "!get_validators" - - "!registry" - - "!DataType" - - "!register_type" - - "!Scalar" - - "!set_children" - - "!validate" - - "!from_str" - - "!from_xml" - - "!model" - - "!validators" - - "!to_object_element" + - "!types_registry" show_bases: true diff --git a/docs/api_reference/errors.md b/docs/api_reference/errors.md new file mode 100644 index 000000000..eb7b1e812 --- /dev/null +++ b/docs/api_reference/errors.md @@ -0,0 +1,7 @@ + + + +::: guardrails.errors + options: + members: + - "ValidationError" \ No newline at end of file diff --git a/docs/api_reference/guard.md b/docs/api_reference/guard.md index 854732d21..57036e557 100644 --- a/docs/api_reference/guard.md +++ b/docs/api_reference/guard.md @@ -4,11 +4,19 @@ ::: guardrails.guard.Guard options: members: + - "__init__" - "from_rail" - "from_rail_string" - "from_pydantic" - "from_string" - "configure" + - "use" + - "use_many" - "__call__" - "parse" - - "state" + - "validate" + - "error_spans_in_output" + - "json_function_calling_tool" + - "to_dict" + - "from_dict" + - "to_runnable" diff --git a/docs/api_reference/rail.md b/docs/api_reference/rail.md deleted file mode 100644 index cab956f4b..000000000 --- a/docs/api_reference/rail.md +++ /dev/null @@ -1,13 +0,0 @@ -::: guardrails.rail.Rail - options: - members: - - "from_file" - - "from_string" - - "from_xml" - - "from_pydantic" - - "from_string_validators" - - "input_schema" - - "output_schema" - - "instructions" - - "prompt" - - "version" \ No newline at end of file diff --git a/docs/api_reference/schema.md b/docs/api_reference/schema.md deleted file mode 100644 index f92f07b90..000000000 --- a/docs/api_reference/schema.md +++ /dev/null @@ -1 +0,0 @@ -::: guardrails.schema \ No newline at end of file diff --git a/docs/api_reference/types.md b/docs/api_reference/types.md new file mode 100644 index 000000000..980475efb --- /dev/null +++ b/docs/api_reference/types.md @@ -0,0 +1 @@ +::: guardrails.types \ No newline at end of file diff --git a/docs/api_reference/validators.md b/docs/api_reference/validators.md deleted file mode 100644 index 447417a4d..000000000 --- a/docs/api_reference/validators.md +++ /dev/null @@ -1,18 +0,0 @@ - - -::: guardrails.validators - options: - filters: - - "!logger" - - "!types_to_validators" - - "!validators_registry" - - "!EventDetail" - - "!Validator" - - "!validate" - - "!register_validator" - - "!PydanticReAsk" - - "!Refrain" - - "!ValidationResult" - - "!PassResult" - - "!FailResult" - - "!__*" diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 000000000..84eaf77ca --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,202 @@ +# Guardrails CLI + +**Usage**: + +```console +$ [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +* `--help`: Show this message and exit. + +**Commands**: + +* `configure` +* `create` +* `hub`: Manage validators installed from the... +* `start` +* `validate`: Validate the output of an LLM against a... +* `watch` + +## `configure` + +**Usage**: + +```console +$ configure [OPTIONS] +``` + +**Options**: + +* `--enable-metrics / --disable-metrics`: Opt out of anonymous metrics collection. [default: enable-metrics] +* `--token TEXT`: API Key for Guardrails. If not provided, you will be prompted for it. +* `--enable-remote-inferencing / --disable-remote-inferencing`: Opt in to remote inferencing. If not provided, you will be prompted for it. [default: enable-remote-inferencing] +* `--clear-token`: Clear the existing token from the configuration file. +* `--help`: Show this message and exit. + +## `create` + +**Usage**: + +```console +$ create [OPTIONS] +``` + +**Options**: + +* `--validators TEXT`: A comma-separated list of validator hub URIs. [required] +* `--name TEXT`: The name of the guard to define in the file. +* `--filepath TEXT`: The path to which the configuration file should be saved. [default: config.py] +* `--dry-run / --no-dry-run`: Print out the validators to be installed without making any changes. [default: no-dry-run] +* `--help`: Show this message and exit. + +## `hub` + +Manage validators installed from the Guardrails Hub. + +**Usage**: + +```console +$ hub [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +* `--help`: Show this message and exit. + +**Commands**: + +* `create-validator`: Lightweight method for creating simple... +* `install` +* `submit`: Submit a validator to the Guardrails AI... +* `uninstall`: Uninstall a validator from the Hub. + +### `hub create-validator` + +Lightweight method for creating simple validators. + +For more complex submissions see here: +https://github.com/guardrails-ai/validator-template?tab=readme-ov-file#how-to-create-a-guardrails-validator + +**Usage**: + +```console +$ hub create-validator [OPTIONS] NAME [FILEPATH] +``` + +**Arguments**: + +* `NAME`: The name for your validator. [required] +* `[FILEPATH]`: The location to write your validator template to `[default: ./{validator_name}.py]` + +**Options**: + +* `--help`: Show this message and exit. + +### `hub install` + +**Usage**: + +```console +$ hub install [OPTIONS] PACKAGE_URI +``` + +**Arguments**: + +* `PACKAGE_URI`: URI to the package to install.Example: hub://guardrails/regex_match. [required] + +**Options**: + +* `--install-local-models / --no-install-local-models`: Install local models +* `--quiet`: Run the command in quiet mode to reduce output verbosity. +* `--help`: Show this message and exit. + +### `hub submit` + +Submit a validator to the Guardrails AI team for review and +publishing. + +**Usage**: + +```console +$ hub submit [OPTIONS] PACKAGE_NAME [FILEPATH] +``` + +**Arguments**: + +* `PACKAGE_NAME`: The package name for your validator. [required] +* `[FILEPATH]`: The location to your validator file. `[default: ./{package_name}.py]` + +**Options**: + +* `--help`: Show this message and exit. + +### `hub uninstall` + +Uninstall a validator from the Hub. + +**Usage**: + +```console +$ hub uninstall [OPTIONS] PACKAGE_URI +``` + +**Arguments**: + +* `PACKAGE_URI`: URI to the package to uninstall. Example: hub://guardrails/regex_match. [required] + +**Options**: + +* `--help`: Show this message and exit. + +## `start` + +**Usage**: + +```console +$ start [OPTIONS] +``` + +**Options**: + +* `--env TEXT`: An env file to load environment variables from. +* `--config TEXT`: A config file to load Guards from. +* `--port INTEGER`: The port to run the server on. [default: 8000] +* `--help`: Show this message and exit. + +## `validate` + +Validate the output of an LLM against a `rail` spec. + +**Usage**: + +```console +$ validate [OPTIONS] RAIL LLM_OUTPUT +``` + +**Arguments**: + +* `RAIL`: Path to the rail spec. [required] +* `LLM_OUTPUT`: String of llm output. [required] + +**Options**: + +* `--out TEXT`: Path to the compiled output directory. [default: .rail_output] +* `--help`: Show this message and exit. + +## `watch` + +**Usage**: + +```console +$ watch [OPTIONS] +``` + +**Options**: + +* `--plain / --no-plain`: Do not use any rich formatting, instead printing each entry on a line. [default: no-plain] +* `--num-lines INTEGER`: Print the last n most recent lines. If omitted, will print all history. [default: 0] +* `--follow / --no-follow`: Continuously read the last output commands [default: follow] +* `--log-path-override TEXT`: Specify a path to the log output file. +* `--help`: Show this message and exit. \ No newline at end of file diff --git a/docs/concepts/async_streaming.ipynb b/docs/concepts/async_streaming.ipynb new file mode 100644 index 000000000..a7199852d --- /dev/null +++ b/docs/concepts/async_streaming.ipynb @@ -0,0 +1,179 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Async Stream-validate LLM responses\n", + "\n", + "Asynchronous behavior is generally useful in LLM applciations. It allows multiple, long-running LLM requests to execute at once. Adding streaming to this situation allows us to make non-blocking, iterative validations over each stream as chunks arrive. This document explores how to implement this behavior using the Guardrails framework.\n", + "\n", + "**Note**: learn more about streaming [here](./streaming).\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Few imports and global variables\n", + "from rich import print\n", + "import guardrails as gd\n", + "import litellm\n", + "from IPython.display import clear_output\n", + "import time" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setup\n", + "\n", + "Install the necessary validators from Guardrails hub in your CLI.\n", + "\n", + "```bash\n", + "!guardrails hub install hub://guardrails/competitor_check\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create the Guard object\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Async Streaming" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from guardrails.hub import CompetitorCheck\n", + "\n", + "prompt = \"Tell me about the Apple Iphone\"\n", + "\n", + "guard = gd.AsyncGuard().use(CompetitorCheck, [\"Apple\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Example 1: No async streaming\n", + "\n", + "By default, the `stream` parameter is set to `False`.\n", + "We will use LiteLLM to make our LLM calls.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Wrap the litellm OpenAI API call with the `guard` object\n", + "raw_llm_output, validated_output, *rest = await guard(\n", + " litellm.acompletion,\n", + " model=\"gpt-3.5-turbo\",\n", + " prompt=prompt,\n", + " max_tokens=1024,\n", + " temperature=0.3,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's see the logs\n", + "print(guard.history.last.tree)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Example 2: Async Streaming\n", + "\n", + "Set the `stream` parameter to `True`\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Wrap the litellm OpenAI API call with the `guard` object\n", + "fragment_generator = await guard(\n", + " litellm.acompletion,\n", + " model=\"gpt-3.5-turbo\",\n", + " prompt=prompt,\n", + " max_tokens=1024,\n", + " temperature=0,\n", + " stream=True,\n", + ")\n", + "\n", + "\n", + "async for op in fragment_generator:\n", + " clear_output(wait=True)\n", + " print(op)\n", + " time.sleep(0.5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's see the logs\n", + "print(guard.history.last.tree)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you can see here, the outputs in both examples match. The only difference is that, in the async streaming example, the outputs are returned as soon as they are received and validated by Guardrails.\n", + "\n", + "In the non-streaming example, the outputs are returned only after the entire request has been processed by the API.\n", + "\n", + "In other words, when async streaming is enabled, the API returns the outputs as soon as they are ready, rather than waiting for the entire request to be processed.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "guard-venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/concepts/deploying.md b/docs/concepts/deploying.md new file mode 100644 index 000000000..170418fad --- /dev/null +++ b/docs/concepts/deploying.md @@ -0,0 +1,89 @@ +# Deploying Guardrails + +This document is a guide on our preffered method to deploy Guardrails to production. We will discuss the new client/server model and the benefits this approach gains us. We'll also look at some patterns we find useful when deploying to a production environment as well as some practices to keep in mind when developing with this new pattern. + +## The Client/Server Model + +### Guardrails As A Service +As part of the v0.5.0 release, we introduced the `guardrails-api`. The Guardrails API offers a way to offload the tasks of initializing and executing Guards to a dedicated server. As of the time of writing this document, this is a simple Flask application that uses the core Guardrails validation engine to interact with Guards over HTTP(S) via a RESTful pattern. There are two main ways you can specify Guards for use on the server: +1. By writing a simple python config file for most use cases +2. By adding a PostgreSQL database for advanced use cases + +We will focus on the first use case in this document. + +### A Quick Demonstration of Using the Guardrails API as a Dev Server +0. *Optional:* We generally recommend utilizing virtual environments. If you don't already have a preference, you can use python's built [venv](https://docs.python.org/3/library/venv.html) module for this. +1. Install Guardrails with the `api` extra: + ```sh + pip install "guardrails-ai[api]" + ``` + +2. Install any validators you need from the hub: + ```sh + guardrails hub install hub://guardrails/regex_match + ``` + +3. Write your Guards in a config.py file: + ```py + # config.py + from guardrails import Guard + from guardrails.hub import RegexMatch + + name_case = Guard( + # This line is important since the Guard's name property will act as the primary key for lookup. + name="name-case", + description="Checks that a string is in Title Case format." + ).use( + RegexMatch(regex="^(?:[A-Z][^\\s]*\\s?)+$") + ) + ``` + +4. Start the Guardrails API + ```sh + guardrails start --config=./config.py + ``` + +5. Reference your Guard by name to use it in your application code: + ```py + from guardrails import Guard, settings + + settings.use_server = True + + name_guard = Guard(name="name-case") + + validation_outcome = name_guard.validate("John Doe") + ``` + +### Why a Client/Server Model? +Moving the computational load of validation off of the client application and onto a dedicated server has many benefits. Beyond enabling potential future enhancements such as proxy implementations and supporting other programming languages with client SDKs, it also solves many of the problems we've encountered ourselves when considering how to best put Guardrails in production. + +Previously, if you were using Guardrails in your application you were also including all of the validators that were part of the core library as well as the models of any of those validators you utilized. This added a lot of overhead to the storage required to run Guardrails on a production server. Beyond this, you also had to account for the resources required to run these models effieciently as part of your production server. As an extreme example, when setting up a server to facilitate the Guardrails Hub playground which included every public validator available for use, the resulting image was over 6GB which is clearly not sustainable. + +In version 0.5.0 as part of the client/server model, all validators were removed from the main repo in favor of selecting only the ones you need from the Guardrails Hub. With this new approach that removes the baggage of maintaining validators within the core Guardrails package, a Docker image of a client application built on python:3.12-slim with a `venv` environment comes in at ~350MB uncompressed. This will continue to decrease as we introduce optimized install profiles for various use cases. + +One last notable improvement we're making to help reduce the impact validator models have on your deployables is introducting remote validation for select validators. With this feature, you can utilize certain validators _without_ downloading or running their underlying models on your hardware. Instead, after a one time configuration, they can offload the heavy lifting to dedicated, remotely hosted models without the need to change the way you interact with the Guardrails package. You can read more about this [here](/concepts/remote_validation_inference). + +So far, we've talked a lot about reducing the resources necessary to run Guardrails in production. Another important factor we considered when shifting to the new client/server paradigm is how this pattern enables better scaling practices. Since the Guardrails API is now separate and distinct from your application code, you can scale both separately and according to their own needs. This means that if your client application needs to scale it can do so without accounting for the additional resources required for validation. Likewise, if the validation traffic is the limiting factor, you client application can stay small on fewer instances while the Guardrails API scales out to meet the demand. You're also not limited to only one Guardrails API deployable giving you the option to scale more heavily utilized use-cases independently of those less frequently used. + + +## Considerations for Productionization +As previously mentioned, the Guardrails API is currently a simple Flask application. This means you'll want a WSGI server to serve the application for a production environment. There are many options out there and we do not particularly endorse one of another. For demonstration purposes we will show using Gunicorn since it is a common choice in the industry. + +Previously we showed how to start the Guardrails API as a dev server using the `guardrails start` command. When launching the Guardrails API with a WSGI server, you will reference the underlying `guardrails_api` module instead. For example, when we Dockerize the Guardrails API for internal use, our final line is: +```Dockerfile +CMD gunicorn --bind 0.0.0.0:8000 --timeout=90 --workers=4 'guardrails_api.app:create_app(None, "config.py")' +``` + +This line starts the Guardrails API Flask application with a gunicorn WSGI server. It specifies what port to bind the server to, as well as the timeout for workers and the maximum number of worker threads for handling requests. We typically use the `gthread` worker class with gunicorn because of compatibility issues between how some async workers try to monkeypatch dependencies and how some libraries specify optional imports. + +The [Official Gunicorn Documentation](https://docs.gunicorn.org/en/latest/design.html#how-many-workers) recommends setting the number of threads/workers to (2 x num_cores) + 1, though this may prove to be too resource intensive, depending on the choice of models in validators. Specifying `--threads=` instead of `--workers=` will cause gunicorn to use multithreading instead of multiprocessing. Threads will be lighter weight, as they can share the models loaded at startup from `config.py`, but [risk hitting race conditions](https://github.com/guardrails-ai/guardrails/discussions/899) when manipulating history. For cases that have several larger models, need longer to process requests, have square-wave-like traffic, or have sustained high traffic, `--threads` may prove to be a desirable tradeoff. + +For further reference, you can find a bare-bones example of Dockerizing the Guardrails API here: https://github.com/guardrails-ai/guardrails-lite-server + + +When selecting a deployment environment it is important to consider what types of validators you plan to use. If most of the validators you require are static or LLM based, the Guardrails API can perform well in a serverless environment. However if you make use of multiple ML based validators, the sheer memory footprint the underlying models bring and the need to load the models on init are good reasons to choose a more persistent hosting option. When utilizing a containerized hosting option that allows for auto-scaling, we find that under load the tasks are generally more CPU bound than memory bound and therefore benefit more from scaling on CPU utilization or request queue depth. + +## Patterns and Practices for Using the Client/Server Model +When considering what to put where when splitting your Guardrails implementation between your client application and the Guardrails API, it mostly comes down to shifting the heavy lifting to the server and keeping your implementation on the client side to a minimum. + +For example, you should define your Guards in the `config.py` that is loaded onto the server, not in your client application. Additionally validators from the Guardrails HUB should also be installed on the server since that is where they will be executed; no need to install these in the client application. This also means that _generally_ any extras you need alongside Guardrails would also be installed server side; that is, you would only want to install `guardails-ai` in your application whereas you would install `guardrails-ai[api]` on the server. This keeps additional dependencies where they belong. \ No newline at end of file diff --git a/docs/concepts/error_remediation.md b/docs/concepts/error_remediation.md new file mode 100644 index 000000000..e9178ed52 --- /dev/null +++ b/docs/concepts/error_remediation.md @@ -0,0 +1,47 @@ +# Error remediation + +## LLM Error Handling and Retries +Guardrails currently performs automatic retries with exponential backoff when any of the following errors occur when calling the LLM: + +- openai.error.APIConnectionError +- openai.error.APIError +- openai.error.TryAgain +- openai.error.Timeout +- openai.error.RateLimitError +- openai.error.ServiceUnavailableError +- An incorrect structure was returned from the LLM + +Guardrails will continue to retry with backoff until a max wait time between requests of sixty (60) seconds is reached. + +Note that this list is not exhaustive of the possible errors that could occur. In the event that errors other than these arise during LLM calls, an exception will be raised. The messaging of this exception is intended to help troubleshoot common problems, especially with custom LLM wrappers, as well as communicate the underlying error. This type of exception would look like the following: + +```log +The callable `fn` passed to `Guard(fn, ...)` failed with the following error: + {Root error message here!}. +Make sure that `fn` can be called as a function that takes in a single prompt string and returns a string. +``` + + +## Validator OnFailActions + +Guardrails provides a number of `OnFailActions` for when a validator fails. The `OnFailAction` specifies the corrective action that should be taken if the quality criteria is not met. The corrective action can be one of the following: + +| Action | Behavior | Supports Streaming? | +|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----| +| `OnFailAction.NOOP` | Do nothing. The failure will still be recorded in the logs, but no corrective action will be taken. | Yes | +| `OnFailAction.EXCEPTION` | Raise an exception when validation fails. | Yes | +| `OnFailAction.REASK` | Reask the LLM to generate an output that meets the correctness criteria specified in the validator. The prompt used for reasking contains information about which quality criteria failed, which is auto-generated by the validator. | No | +| `OnFailAction.FIX` | Programmatically fix the generated output to meet the correctness criteria when possible. E.g. the formatter `provenance_llm` validator will remove any sentences that are estimated to be hallucinated. | No | +| `OnFailAction.FILTER` | (Only applicable for structured data validation) Filter the incorrect value. This only filters the field that fails, and will return the rest of the generated output. | No | +| `OnFailAction.REFRAIN` | Refrain from returning an output. This is useful when the generated output is not safe to return, in which case a `None` value is returned instead. | No | +| `OnFailAction.FIX_REASK` | First, fix the generated output deterministically, and then rerun validation with the deterministically fixed output. If validation fails, then perform reasking. | No | + + +## Guidance on dealing with Validator errors + +When a validator fails, Guardrails does two things + +1. logs the failure in history (accessible via `guard.history.last.failed_validations`) +2. takes the corrective action specified by the `on_fail` action on the validator + +While Reasks and Fixes are useful for simple usecase, as usecases get more complex, we recommend switching to an exception-based approach. This is because exceptions provide more flexibility in handling errors, and can be used to implement more complex error handling logic. They can also be used to more effectively route your LLM app along different paths based on the type of error that occured and which set of validators failed. \ No newline at end of file diff --git a/docs/concepts/guard.md b/docs/concepts/guard.md new file mode 100644 index 000000000..831b2d362 --- /dev/null +++ b/docs/concepts/guard.md @@ -0,0 +1,90 @@ +# The Guard + +The guard object is the main interface for Guardrails. It can be used without configuration for string-based LLM apps, and accepts a pydantic object for structured data usecases. The Guard is then used to run the Guardrails AI engine. It is the object that wraps LLM calls, orchestrates validation, and keeps track of call history. + + +## How it works + +![Guardrails Logo](../img/guardrails_arch_white_vertical.png#only-light) +![Guardrails Logo](../img/guardrails_arch_dark_vertical.png#only-dark) + + +## Two main flows +### __call__ +After initializing a guard, you can invoke it using a model name and messages for your prompt, similarly to how you would invoke a regular call to an LLM SDK. Guardrails will call the LLM and then validate the output against the guardrails you've configured. The output will be returned as a `GuardResponse` object, which contains the raw LLM output, the validated output, and whether or not validation was successful. + +```py +from guardrails import Guard +import os + +# Set your openai API key here +# os.environ["OPENAI_API_KEY"] = [YOUR API KEY] + +guard = Guard() + +res = guard( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": "How do I make a cake?" + }] +) + +print(res.raw_llm_output) +print(res.validated_output) +print(res.validation_passed) +``` + +### parse +If you would rather call the LLM yourself, or at least make the first call yourself, you can use `Guard.parse` to apply your RAIL specification to the LLM output as a post process. You can also allow Guardrails to make re-asks to the LLM by specifying the `num_reasks` argument, or keep it purely as a post-processor by setting it to zero. `Guard.parse` returns the same fields as `__call__`. + +Calling `Guard.parse` as a post-processor: +```py +import openai +from guardrails import Guard + +guard = Guard() + +output = openai.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": "How do I make a cake?" + }] +).choices[0].message.content + +res = guard.parse( + llm_output=output +) + +print(res.validated_output) # Validated output +``` + +Calling `Guard.parse` with reasks: +```py +import openai +from guardrails import Guard + +guard = Guard() + +output = openai.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": "How do I make a cake?" + }] +).choices[0].message.content + +res = guard.parse( + llm_output=output, + model="gpt-3.5-turbo", + num_reasks=1 +) + +print(res.validated_output) # Validated output +print(guard.history.last.reasks) # A list of reasks +``` + +## Error Handling and Retries + +Guardrails is designed to account for different types of errors that can occur when calling the LLM, and it is also designed to emit helpful errors when validations fail. Read more about error handling and retries [here](./error_remediation). \ No newline at end of file diff --git a/tests/unit_tests/validators/__init__.py b/docs/concepts/guardrails.md similarity index 100% rename from tests/unit_tests/validators/__init__.py rename to docs/concepts/guardrails.md diff --git a/docs/concepts/hub.md b/docs/concepts/hub.md new file mode 100644 index 000000000..6d4a8e516 --- /dev/null +++ b/docs/concepts/hub.md @@ -0,0 +1,17 @@ +# Guardrails Hub + +The Guardrails Hub is a community-driven effort to create and share guardrails for common LLM validation use cases. The Hub is a place where you can find guardrails for common LLM validation use cases, and also contribute your own guardrails to help others. You can check out the hub at [here](https://hub.guardrailsai.com). + +The hub allows you to mix and match guardrails and build your own “guard” that runs in your critical path in production, and makes sure that when any of the risks in your guard occur, then an appropriate action is taken. + +## Guardrails + +Guardrails are a set of ML models or rules that are used to validate the output of a language model. They are used to ensure that the output of the model is safe, accurate, and meets the requirements of the user. Guardrails can be used to check for things like bias, toxicity, and other issues that may arise from using a language model. + +Each guardrail validates the presence of a specific type of risk – that risk may range from unsafe code, hallucinations, regulation violations, company disrepute, toxicity or unsatisfactory user experience. Some examples of guardrails on the hub are: +- Anti-Hallucination guardrails +- No mentions of Competitors (for an organization) +- No toxic language +- Accurate summarization +- PII Leakage +- For code-gen use cases — generating invalid / unsafe code \ No newline at end of file diff --git a/docs/concepts/logs.md b/docs/concepts/logs.md new file mode 100644 index 000000000..69f81c978 --- /dev/null +++ b/docs/concepts/logs.md @@ -0,0 +1,189 @@ +# Logs and History + +All `Guard` calls are logged internally, and can be accessed via the guard history. + +## Accessing logs via `Guard.history` + +Each entry in the history stack is a `Call` log which will contain information specific to a particular `Guard.__call__` or `Guard.parse` call in the order that they were executed within the current session. + +For example, if you have a guard: + +```py +my_guard = Guard.from_rail(...) +``` + +and you call it multiple times: + +```py +response_1 = my_guard(...) + +response_2 = my_guard.parse(...) +``` + +Then `guard.history` will have two call logs with the first representing the first call `response_1 = my_guard(...)` and the second representing the following `parse` call `response_2 = my_guard.parse(...)`. + +To pretty print logs for the latest call, run: + +```python +from rich import print + +print(guard.history.last.tree) +``` +--8<-- + +docs/html/single-step-history.html + +--8<-- + +The `Call` log will contain initial and final information about a particular guard call. + +```py +first_call = my_guard.history.first +``` + +For example, it tracks the initial inputs as provided: +```py +print("prompt\n-----") +print(first_call.prompt) +print("prompt params\n------------- ") +print(first_call.prompt_params) +``` +```log +prompt +----- + +You are a human in an enchanted forest. You come across opponents of different types. You should fight smaller opponents, run away from bigger ones, and freeze if the opponent is a bear. + +You run into a ${opp_type}. What do you do? + +${gr.complete_xml_suffix_v2} + + +Here are a few examples + +goblin: {"action": {"chosen_action": "fight", "weapon": "crossbow"}} +troll: {"action": {"chosen_action": "fight", "weapon": "sword"}} +giant: {"action": {"chosen_action": "flight", "flight_direction": "north", "distance": 1}} +dragon: {"action": {"chosen_action": "flight", "flight_direction": "south", "distance": 4}} +black bear: {"action": {"chosen_action": "freeze", "duration": 3}} +beets: {"action": {"chosen_action": "fight", "weapon": "fork"}} + +prompt params +------------- +{'opp_type': 'grizzly'} +``` + +as well as the final outputs: +```py +print("status: ", first_call.status) # The final status of this guard call +print("validated response:", first_call.validated_output) # The final valid output of this guard call +``` +```log +status: pass +validated response: {'action': {'chosen_action': 'freeze', 'duration': 3}} +``` + + +The `Call` log also tracks cumulative values from any iterations that happen within the call. + +For example, if the first response from the LLM fails validation and a reask occurs, the `Call` log can provide total tokens consumed (*currently only for OpenAI models), as well as access to all of the raw outputs from the LLM: +```py +print("prompt token usage: ", first_call.prompt_tokens_consumed) # Total number of prompt tokens consumed across iterations within this call +print("completion token usage: ", first_call.completion_tokens_consumed) # Total number of completion tokens consumed across iterations within this call +print("total token usage: ",first_call.tokens_consumed) # Total number of tokens consumed; equal to the sum of the two values above +print("llm responses\n-------------") # An Stack of the LLM responses in order that they were received +for r in first_call.raw_outputs: + print(r) +``` +```log +prompt token usage: 909 +completion token usage: 57 +total token usage: 966 + +llm responses +------------- +{"action": {"chosen_action": "freeze"}} +{ + "action": { + "chosen_action": "freeze", + "duration": null + } +} +{ + "action": { + "chosen_action": "freeze", + "duration": 1 + } +} +``` + +For more information on `Call`, see the [History & Logs](/docs/api_reference_markdown/history_and_logs) page. + +## 🇻🇦 Accessing logs from individual steps +In addition to the cumulative values available directly on the `Call` log, it also contains a `Stack` of `Iteration`'s. Each `Iteration` represent the logs from within a step in the guardrails process. This includes the call to the LLM, as well as parsing and validating the LLM's response. + +Each `Iteration` is treated as a stateless entity so it will only contain information about the inputs and outputs of the particular step it represents. + +For example, in order to see the raw LLM response as well as the logs for the specific validations that failed during the first step of a call, we can access this information via that steps `Iteration`: + +```py +first_step = first_call.iterations.first + +first_llm_output = first_step.raw_output +print("First LLM response\n------------------") +print(first_llm_output) +print(" ") + +validation_logs = first_step.validator_logs +print("\nValidator Logs\n--------------") +for log in validation_logs: + print(log.json(indent=2)) +``` +```log +First LLM response +------------------ +{"action": {"chosen_action": "fight", "weapon": "spoon"}} + + +Validator Logs +-------------- +{ + "validator_name": "ValidChoices", + "value_before_validation": "spoon", + "validation_result": { + "outcome": "fail", + "metadata": null, + "error_message": "Value spoon is not in choices ['crossbow', 'axe', 'sword', 'fork'].", + "fix_value": null + }, + "value_after_validation": { + "incorrect_value": "spoon", + "fail_results": [ + { + "outcome": "fail", + "metadata": null, + "error_message": "Value spoon is not in choices ['crossbow', 'axe', 'sword', 'fork'].", + "fix_value": null + } + ], + "path": [ + "action", + "weapon" + ] + } +} +``` + +Similar to the `Call` log, we can also see the token usage for just this step: +```py +print("prompt token usage: ", first_step.prompt_tokens_consumed) +print("completion token usage: ", first_step.completion_tokens_consumed) +print("token usage for this step: ",first_step.tokens_consumed) +``` +```log +prompt token usage: 617 +completion token usage: 16 +token usage for this step: 633 +``` + +For more information on the properties available on `Iteration`, see the [History & Logs](/docs/api_reference_markdown/history_and_logs/#guardrails.classes.history.Iteration) page. \ No newline at end of file diff --git a/docs/concepts/parallelization.md b/docs/concepts/parallelization.md new file mode 100644 index 000000000..1c4a069e5 --- /dev/null +++ b/docs/concepts/parallelization.md @@ -0,0 +1,98 @@ +# Parallelization +## And the Orchestration of Guard Executions + +This document is a description of the current implementation of the Guardrails' validation loop. It attempts to explain the current patterns used with some notes on why those patterns were accepted at the time of implementation and potential future optimizations. It is _not_ meant to be prescriptive as there can, and will, be improvements made in future versions. + +In general you will find that our approach to performance is two fold: +1. Complete computationally cheaper, static checks first and exit early to avoid spending time and resources on more expensive checks that are unlikely to pass when the former fail. +2. Parallelize processing where possible. + +## Background: The Validation Loop +When a Guard is executed, that is called via `guard()`, `guard.parse()`, `guard.validate()`, etc., it goes through an internal process that has the following steps: + +1. Call the LLM +2. Parse the output +3. Validate the output +4. Reask if necessary + +Each of these steps can potentially have sub-steps as well as breakpoints to end the validation loop early if future steps cannot be sucessfully or meaningfully run. + +### Calling the LLM +If a Guard is called with an `llm_output`, this step is essentially a no-op as we just return the passed in value in the same format we would have expected it from the LLM. + +However, if no `llm_output` is provided but instead an `llm_api` is, then the LLM is called with as many of the arguments passed through as transparently as possible. If an exception is raised or if the LLM does not return the proper content type, then the validation loop exits early raising a `PromptCallableException`. + + > NOTE: `PromptCallableException` used to serve the purpose of enabling retries. As of v0.4.5 though, we only attempt retries for OpenAI 0.x. Since we drop support for 0.x in v0.5.0, we no longer attempt retries, making `PromptCallableException` obsolete. We should therefore consider its removal. + +### Parsing the LLM Output +Regardless if the output was provided by the user or by calling an LLM, it undergoes three distinct parsing steps before validation: + +1. Extraction - This step attempts to extract JSON from an LLM response. It uses a combination of code block detection and regex to retrieve only the JSON content from responses such as: + ```` + Sure! Here's the JSON you asked for: + + ``` + { + "foo": "bar" + } + ``` + ```` +2. Pruning - This step removes extra properties from the response that are not specified by the output structure. This step _does_ allow for `additionalProperties` specified through JSON Schema, `json_schema_extra`'s in Pydantic, or `` tags without any child elements in RAIL. +3. Type Coercion - This steps attempts to correct any disparities in types between the specified output structure and the LLM output. For example, if a property is specified as an `int` but the LLM returns `"1"`, this step will convert `"1"` -> `1`. + > NOTE: This step requires a full traversal of the output schema and LLM output. While this process is much less expensive than a Reask, we should allow users to disable this step if they wish. + +### Validating the LLM Output +Once the output has been parsed it then undergoes validation. Validation currently happens in two steps: + +1. Schema verification - This step ensures that the output matches the schema provided for the output structure. If the output does not meet the requirements of the schema (e.g. missing properties, unallowed extra properties, incorrect types, etc.), then the validation loop exists early and a `SkeletonReask` is returned. + > NOTE: This step also requires a full traversal of the output schema and LLM output. While this process is much less expensive than running validators which utilize large models, we should allow users to disable this step if they wish. +2. Validator execution - This step is likely the most obvious; this is when the validators specified in the Guard are run against the output that has undergone the previous steps. We will dive into more detail on how these are run below, but in short this step runs the validator and applies the specified on fail actions if the validator results in a `FailResult`. On fail actions are applied by replacing the value in the output with the appropriate substitute; i.e. a `Filter`, `Refrain`, `FieldReAsk`, or a fixed value. + +### Reasking the LLM +The final step in the validation loop is also an optional one. If you allow Guardrails to make calls to the LLM by providing the `llm_api` argument, and allow reasks by setting `num_reask` to a value greater than zero, then in the event of validation failure a reask prompt is constructed and sent to the LLM with information about what was wrong with it's previous response. If a reasks are enabled, then the validation loop runs until either validation is sucessful or the maximum number of reasks allowed have been used. + +## Async vs Sync +In previous version of Guardrails there was not a strong distinction within the interfaces to specify synchronous or asynchronous flows. It purely depended on whether the `llm_api` argument was a coroutine or not. This led to complicated overloads to try to accurately represent the return types as well as ambiguity around what was happening during validation. In v0.4.5, we introduced the `AsyncGuard` class, and in v0.5.0 we are removing asynchronous support from the `Guard` class entirely in favor of using the `AsyncGuard` class for this purpose. + +### Benefits of AsyncGuard +Besides handling asynchronous calls to the LLM, using an `AsyncGuard` also ensures that validation occurs in an asynchronos manner. A `Guard`, on the other hand, will only utilize asynchronous validation under the following conditions: +* The `GUARDRAILS_PROCESS_COUNT` environment variable is unset, or set to a integer value greater than 1. +* An asyncio event loop is available. +* The asyncio event loop is not taken/already running. + +## Validation Orchestration and Parallelization + +### Structured Data Validation +We perform validation with a "deep-first" approach. This has no meaning for unstructured text output since there is only one value, but for structured output it means that the objects are validated from the inside out. + +Take the below structure as an example: +```json +{ + "foo": { + "baz": 1, + "bez": 2 + }, + "bar": { + "biz": 1, + "buz": 2 + } +} +``` + +As of versions v0.4.x and v0.5.x of Guardrails, the above object would validated as follows: + +1. foo.baz +2. foo.bez +3. foo +4. bar.biz +5. bar.buz +6. bar + + > NOTE: The approach currently used, and outlined above, was predicated on the assumption that if child properties fail validation, it is unlikely that the parent property would pass. With the current atomic state of validation, it can be argued that this assumption is false. That is, the types of validations applied to parent properties typically take the form of checking the appropriate format of the container like a length check on a list. These types of checks are generally independent of any requirements the child properties have. This opens up the possibility of running all six paths listed above in parallel at once instead of performing them in steps based on key path. + +When synchronous validation occurs as defined in [Benefits of AsyncGuard](#benefits-of-async-guard), the validators for each property would be run in the order they are defined on the schema. That also means that any on fail actions are applied in that same order. + +When asynchronous validation occurs, there are multiple levels of parallelization possible. First, running validation on the child properties (e.g. `foo.baz` and `foo.bez`) will happen in parallel via the asyncio event loop. Second, within the validation for each property, if the validators have `run_in_separate_process` set to `True`, they are run in parallel via multiprocessing. This multiprocessing is capped to the process count specified by the `GUARDRAILS_PROCESS_COUNT` environment variable which defaults to 10. Note that some environments, like AWS Lambda, may not support multiprocessing in which case you would need to set this environment variable to 1. + +### Unstructured Data Validation +When validating unstructured data, i.e. text, the LLM output is treated the same as if it were a property on an object. This means that the validators applied to is have the ability to run in parallel utilizing multiprocessing when `run_in_separate_process` is set to `True` on the validators. \ No newline at end of file diff --git a/docs/concepts/remote_validation_inference.ipynb b/docs/concepts/remote_validation_inference.ipynb new file mode 100644 index 000000000..e5b7b332d --- /dev/null +++ b/docs/concepts/remote_validation_inference.ipynb @@ -0,0 +1,134 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remote Validation Inference\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Guardrails now supports validation through API endpoints! By providing a url when initialized a validator, you are now able to have the validator send a request for ML accelerated validation at an API endpoint. Guardrails has setup a series of endpoints to help you get started.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To use an guardrails endpoint, you simply need to find a validator that has implemented support. Validators with a Guardrails hosted endpoint are labeled as such on the [Validator Hub](https://hub.guardrailsai.com). One example is ToxicLanguage." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!guardrails hub install hub://guardrails/toxic_language --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from guardrails import Guard\n", + "from guardrails.hub import ToxicLanguage" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "guard = Guard().use(\n", + " ToxicLanguage\n", + " # Uncomment the following line to use a local version of the model\n", + " # To download the model, run `guardrails hub install` with the --install-local-models flag\n", + " # use_local=True\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The major benefit of hosting a validator inference endpoint is the increase in speed and throughput compared to running locally. This implementation makes use cases such as streaming much more viable!\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import display, clear_output\n", + "\n", + "fragment_generator = guard(\n", + " model=\"gpt-3.5-turbo\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": \"Tell me about the Apple Iphone.\"},\n", + " ],\n", + " max_tokens=1024,\n", + " temperature=0,\n", + " stream=True,\n", + ")\n", + "\n", + "\n", + "\n", + "accumulated_output = \"\"\n", + "for op in fragment_generator:\n", + " clear_output()\n", + " accumulated_output += op.validated_output\n", + " display(accumulated_output)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You are also able to host an endpoint! Just implement the required inference logic and host it on your own server.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "guard = Guard().use(\n", + " ToxicLanguage,\n", + " use_local=False,\n", + " validation_endpoint=\"your_endpoint_ip_address\",\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/concepts/streaming.ipynb b/docs/concepts/streaming.ipynb new file mode 100644 index 000000000..384b3cb03 --- /dev/null +++ b/docs/concepts/streaming.ipynb @@ -0,0 +1,159 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Streaming" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In production systems with user interaction, streaming output from LLMs greatly improves the user experience. Streaming allows you to build real-time systems that minimize the time to first token (TTFT) rather than waiting for the entire document to be completed before progessing.\n", + "\n", + "\n", + "Guardrails natively supports validation for streaming output, supporting both synchronous and asynchronous approaches." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from rich import print\n", + "import guardrails as gd\n", + "import litellm\n", + "from IPython.display import clear_output\n", + "import time" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Streaming with a guard class can be done by setting the 'stream' parameter to 'True'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from guardrails.hub import CompetitorCheck\n", + "prompt = \"Tell me about the Apple Iphone\"\n", + "\n", + "guard = gd.Guard().use(CompetitorCheck, [\"Apple\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fragment_generator = guard(\n", + " litellm.completion,\n", + " model=\"gpt-4o\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": \"Tell me about LLM streaming APIs.\"},\n", + " ],\n", + " max_tokens=1024,\n", + " temperature=0,\n", + " stream=True,\n", + ")\n", + "\n", + "\n", + "for op in fragment_generator:\n", + " clear_output(wait=True)\n", + " print(op)\n", + " time.sleep(0.5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With streaming, not only do chunks from the LLM arrive as they are generated, but validation results can stream in real time as well.\n", + "\n", + "To do this, validators specify a chunk strategy. By default, validators wait until they have accumulated a sentence's worth of content from the LLM before running validation. Once they've run validation, they emit that result in real time. \n", + "\n", + "In practice, this means that you do not have to wait until the LLM has finished outputting tokens to access validation results, which helps you create smoother and faster user experiences. It also means that validation can run only on individual sentences, instead of the entire accumulated response, which helps save on costs for validators that require expensive inference.\n", + "\n", + "To access these validation results, use the error_spans_in_output helper method on Guard. This will provide an up to date list of all ranges of text in the output so far that have failed validation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "error_spans = guard.error_spans_in_output()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Async Streaming\n", + "\n", + "In cases where concurrent network calls are happening (many LLM calls!) it may be beneficial to use an asynchronous LLM client. Guardrails also natively supports asynchronous streaming calls.\n", + "\n", + "Learn more about async streaming [here](./async_streaming)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "guard = gd.Guard()\n", + "\n", + "fragment_generator = await guard(\n", + " litellm.completion,\n", + " model=\"gpt-3.5-turbo\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": \"Tell me about the streaming API of guardrails.\"},\n", + " ],\n", + " max_tokens=1024,\n", + " temperature=0,\n", + " stream=True,\n", + ")\n", + "\n", + "\n", + "async for op in fragment_generator:\n", + " clear_output(wait=True)\n", + " print(op)\n", + " time.sleep(0.5)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/how_to_guides/streaming.ipynb b/docs/concepts/streaming_structured_data.ipynb similarity index 97% rename from docs/how_to_guides/streaming.ipynb rename to docs/concepts/streaming_structured_data.ipynb index 1e3254120..976543aa9 100644 --- a/docs/how_to_guides/streaming.ipynb +++ b/docs/concepts/streaming_structured_data.ipynb @@ -4,19 +4,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Stream-validate LLM responses\n" + "# Streaming Structured Data\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Few imports and global variables\n", "from rich import print\n", "import guardrails as gd\n", - "import openai\n", + "import litellm\n", "from IPython.display import clear_output\n", "import time" ] @@ -53,59 +53,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/zaydsimjee/workspace/guardrails/guardrails/validators/__init__.py:50: FutureWarning: \n", - " Importing validators from `guardrails.validators` is deprecated.\n", - " All validators are now available in the Guardrails Hub. Please install\n", - " and import them from the hub instead. All validators will be\n", - " removed from this module in the next major release.\n", - "\n", - " Install with: `guardrails hub install hub:///`\n", - " Import as: from guardrails.hub import `ValidatorName`\n", - " \n", - " warn(\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/guardrails/validator_base.py:397: FutureWarning: Accessing `LowerCase` using\n", - "`from guardrails.validators import LowerCase` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import LowerCase` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/lowercase.\n", - "\n", - " warn(\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/guardrails/validator_base.py:397: FutureWarning: Accessing `UpperCase` using\n", - "`from guardrails.validators import UpperCase` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import UpperCase` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/uppercase.\n", - "\n", - " warn(\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/guardrails/validator_base.py:397: FutureWarning: Accessing `ValidRange` using\n", - "`from guardrails.validators import ValidRange` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import ValidRange` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/valid_range.\n", - "\n", - " warn(\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/guardrails/validator_base.py:397: FutureWarning: Accessing `OneLine` using\n", - "`from guardrails.validators import OneLine` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import OneLine` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/one_line.\n", - "\n", - " warn(\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from pydantic import BaseModel, Field\n", "from guardrails.hub import LowerCase, UpperCase, ValidRange, OneLine\n", @@ -116,7 +66,7 @@ "\n", "${doctors_notes}\n", "\n", - "${gr.complete_json_suffix_v2}\n", + "${gr.complete_xml_suffix_v2}\n", "\"\"\"\n", "\n", "doctors_notes = \"\"\"152 y/o female with chronic macular rash to face and hair, worse in beard, eyebrows and nares.\n", @@ -168,11 +118,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "guard = gd.Guard.from_pydantic(output_class=PatientInfo, prompt=prompt)" + "guard = gd.Guard.from_pydantic(output_class=PatientInfo)" ] }, { @@ -186,7 +136,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -233,9 +183,11 @@ } ], "source": [ - "# Wrap the OpenAI API call with the `guard` object\n", + "# Wrap the litellm OpenAI API call with the `guard` object\n", "raw_llm_output, validated_output, *rest = guard(\n", - " openai.chat.completions.create,\n", + " litellm.completion,\n", + " model=\"gpt-3.5-turbo\",\n", + " prompt=prompt,\n", " prompt_params={\"doctors_notes\": doctors_notes},\n", " max_tokens=1024,\n", " temperature=0.3,\n", @@ -247,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -454,7 +406,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -536,9 +488,10 @@ } ], "source": [ - "# Wrap the OpenAI API call with the `guard` object\n", + "# Wrap the litellm OpenAI API call with the `guard` object\n", "fragment_generator = guard(\n", - " openai.chat.completions.create,\n", + " litellm.completion,\n", + " model=\"gpt-3.5-turbo\",\n", " prompt_params={\"doctors_notes\": doctors_notes},\n", " max_tokens=1024,\n", " temperature=0,\n", @@ -554,7 +507,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -863,32 +816,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/zaydsimjee/workspace/guardrails/guardrails/validator_base.py:397: FutureWarning: Accessing `UpperCase` using\n", - "`from guardrails.validators import UpperCase` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import UpperCase` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/uppercase.\n", - "\n", - " warn(\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/guardrails/validator_base.py:397: FutureWarning: Accessing `OneLine` using\n", - "`from guardrails.validators import OneLine` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import OneLine` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/one_line.\n", - "\n", - " warn(\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from guardrails.hub import UpperCase, OneLine\n", "\n", @@ -917,7 +847,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -965,9 +895,10 @@ } ], "source": [ - "# Wrap the OpenAI API call with the `guard` object\n", + "# Wrap the litellm OpenAI API call with the `guard` object\n", "raw, validated, *rest = guard(\n", - " openai.chat.completions.create,\n", + " litellm.completion,\n", + " model=\"gpt-3.5-turbo\",\n", " max_tokens=50,\n", " temperature=0.1,\n", ")\n", @@ -988,7 +919,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1024,15 +955,15 @@ } ], "source": [ - "# Wrap the OpenAI API call with the `guard` object\n", + "# Wrap the litellm OpenAI API call with the `guard` object\n", "fragment_generator = guard(\n", - " openai.chat.completions.create,\n", + " litellm.completion,\n", + " model=\"gpt-3.5-turbo\",\n", " max_tokens=50,\n", " temperature=0.1,\n", " stream=True,\n", ")\n", "\n", - "\n", "for op in fragment_generator:\n", " clear_output(wait=True)\n", " print(op)\n", @@ -1041,7 +972,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1113,9 +1044,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As you can see, the outputs in both examples match. The only difference is that, in the streaming example, the outputs are returned as soon as they are received and validated by Guardrails. In the non-streaming example, the outputs are returned only after the entire request has been processed by the API. In other words, when streaming is enabled, the API returns the outputs as soon as they are ready, rather than waiting for the entire request to be processed.\n", - "\n", - "This also works with openai's chat completion API.\n" + "As you can see, the outputs in both examples match. The only difference is that, in the streaming example, the outputs are returned as soon as they are received and validated by Guardrails. In the non-streaming example, the outputs are returned only after the entire request has been processed by the API. In other words, when streaming is enabled, the API returns the outputs as soon as they are ready, rather than waiting for the entire request to be processed." ] } ], @@ -1135,7 +1064,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.7" + "version": "3.11.8" } }, "nbformat": 4, diff --git a/docs/concepts/telemetry.mdx b/docs/concepts/telemetry.mdx new file mode 100644 index 000000000..b1561d743 --- /dev/null +++ b/docs/concepts/telemetry.mdx @@ -0,0 +1,84 @@ +# Telemetry + +## Our approach to telemetry + +Telemetry is a crucial part of the LLM toolcahin in production. LLMs are nondeterministic and work with relatively high latency compared to more traditional APIs. This makes it important to monitor production systems that use LLMs, as well as the LLMs themselves. + +Basic LLM telemetry like token count and latency is important. + +It's as important to monitor the performance of the Guards that protect your LLMs. +By integrating telemetry, we can find how effective our guards are and how much latency they add to the system. + + +## Metrics you can capture using OTEL + +This package is instrumented using the OpenTelemetry Python SDK. By viewing the captured traces and derived metrics, we're able to get useful insights into how our Guards, and our LLM apps in general perform. Among other things, we're able to find: + +1. Latency of Guards +2. Latency of LLMs +3. Success rates of Guards +4. The rate at which validators Pass and Fail, within a Guard and across Guards +5. Deep dives into singular guard and validator calls + +Since we are using OpenTelemetry, traces and metrics can be written to any OpenTelemetry-enabled service or OTLP endpoint. This includes all major metrics providers like Grafana, New Relic, Prometheus, and Splunk. + +This guide will show how to set up your Python project to log traces to Grafana and to a self-hosted OTEL collector. For other OTEL endpoints, consult your metrics provider's documentation on OTEL support. + +## Configure Guardrails to talk to an OTLP collector + +To talk to an OTLP collector, you need only add a few environment variables and set the `tracer` attribute of your Guard to the default OTLP tracer provided by Guardrails. + +First, set these environment variables + +```bash +OTEL_EXPORTER_OTLP_PROTOCOL +OTEL_EXPORTER_OTLP_ENDPOINT +OTEL_EXPORTER_OTLP_HEADERS +``` + +Then, add the tracer provider to your guard: + +```python +from guardrails.utils.telemetry_utils import default_otlp_tracer + +# define your guard +guard = Guard() + +guard.configure(tracer=default_otlp_tracer("my_guard")) + +``` + +## Configure OTEL for a self-hosted OpenTelemetry Collector + +For advanced use cases (like if you have a metrics provider in a VPC), you can use a self-hosted OpenTelemetry Collector to receive traces and metrics from your Guard. +Standard [open telemetry environment variables](https://opentelemetry.io/docs/languages/python/exporters/) are used to configure the collector. Use the `default_otel_collector_tracer` when configuring your guard. + +```python +from guardrails import Guard, OnFailAction +from guardrails.utils.telemetry_utils import default_otel_collector_tracer +from guardrails.hub import ValidLength + +guard = Guard().use( + validators=[ValidLength(min=1, max=10, on_fail=OnFailAction.EXCEPTION)], +) +guard.configure( + # use a descriptive name that will differentiate where your metrics are stored + tracer=default_otel_collector_tracer("petname_guard") +) + +guard( + messages[{ + "role": "user", + "content": "Suggest a name for my cat." + }], + model="gpt-4", + max_tokens=1024, + temperature=0.5, +) +``` + +## Learn more +Check out one of our partner integrations to see how you can use Guardrails with your favorite metrics provider. + +- [Arize](https://docs.arize.com/arize/large-language-models/guardrails) +- [Grafana](../integrations/telemetry/grafana) \ No newline at end of file diff --git a/docs/examples/bug_free_python_code.ipynb b/docs/examples/bug_free_python_code.ipynb index d377b4eb5..c381ce574 100644 --- a/docs/examples/bug_free_python_code.ipynb +++ b/docs/examples/bug_free_python_code.ipynb @@ -10,7 +10,7 @@ "!!! note\n", " To download this tutorial as a Jupyter notebook, click [here](https://github.com/guardrails-ai/guardrails/blob/main/docs/examples/bug_free_python_code.ipynb).\n", "\n", - "In this example, we want to solve String Maniuplation leetcode problems such that the code is bug free.\n", + "In this example, we want to solve String Manipulation leetcode problems such that the code is bug free.\n", "\n", "We make the assumption that:\n", "\n", @@ -23,14 +23,14 @@ "\n", "In short, we want to make sure that the code can be executed without any errors.\n", "\n", - "## Step 1: Generating `RAIL` Spec\n", + "## Step 1: Install validators from the hub\n", "\n", - "First, we install the validators and packages we need to make sure generated python is valid. Then, we generate a RAIL spec as a pydantic model." + "First, we install the validators and packages we need to make sure generated python is valid." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -49,68 +49,24 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pydantic import BaseModel, Field\n", - "from guardrails.hub import ValidPython\n", - "\n", - "prompt = \"\"\"\n", - "Given the following high level leetcode problem description, write a short Python code snippet that solves the problem.\n", - "\n", - "Problem Description:\n", - "${leetcode_problem}\n", - "\n", - "${gr.complete_json_suffix}\"\"\"\n", - "\n", - "class BugFreePythonCode(BaseModel):\n", - " python_code: str = Field(validators=[ValidPython(on_fail=\"reask\")])\n", - "\n", - " class Config:\n", - " arbitrary_types_allowed = True" - ] - }, - { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 2: Create a `Guard` object with the RAIL Spec\n", - "\n", - "We create a `gd.Guard` object that will check, validate and correct the generated code. This object:\n", + "# Step 2: Create a `Guard` object\n", "\n", - "1. Enforces the quality criteria specified in the RAIL spec (i.e. bug free code).\n", - "2. Takes corrective action when the quality criteria are not met (i.e. reasking the LLM).\n", - "3. Compiles the schema and type info from the RAIL spec and adds it to the prompt." + "The Guard object contains the validations we aim to check the generated code against. This object also takes corrective action to fix the code if it doesn't pass the validations. As configured here, it will reask the LLM to correct the code." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ - "import guardrails as gd\n", + "from guardrails.hub import ValidPython\n", + "from guardrails import Guard\n", "\n", - "from rich import print" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or from the pydantic model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "guard = gd.Guard.from_pydantic(output_class=BugFreePythonCode, prompt=prompt)" + "guard = Guard().use(ValidPython(on_fail=\"reask\"))" ] }, { @@ -118,72 +74,64 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The `Guard` object compiles the output schema and adds it to the prompt. We can see the final prompt below:" + "## Step 3: Use the `Guard` to make and validate the LLM API call" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
\n",
-       "Given the following high level leetcode problem description, write a short Python code snippet that solves the \n",
-       "problem.\n",
-       "\n",
-       "Problem Description:\n",
-       "${leetcode_problem}\n",
-       "\n",
-       "\n",
-       "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
-       "\n",
-       "<output>\n",
-       "    <string name=\"python_code\" format=\"reflex/valid_python\"/>\n",
-       "</output>\n",
-       "\n",
-       "\n",
-       "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n",
-       "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n",
-       "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n",
-       "specific types. Be correct and concise. If you are unsure anywhere, enter `null`.\n",
-       "\n",
-       "Here are examples of simple (XML, JSON) pairs that show the expected behavior:\n",
-       "- `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`\n",
-       "- `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO', etc.]}`\n",
-       "- `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\" format=\"1-indexed\" \n",
-       "/></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`\n",
-       "\n",
+       "
ValidationOutcome(\n",
+       "    call_id='12105167920',\n",
+       "    raw_llm_output='def longest_palindromic_substring(s):\\n    n = len(s)\\n    if n == 0:\\n        return \"\"\\n    \n",
+       "\\n    start, max_length = 0, 1\\n    \\n    for i in range(1, n):\\n        low, high = i - 1, i\\n        while low >=\n",
+       "0 and high < n and s[low] == s[high]:\\n            if high - low + 1 > max_length:\\n                start = low\\n  \n",
+       "max_length = high - low + 1\\n            low -= 1\\n            high += 1\\n        \\n        low, high = i - 1, i + \n",
+       "1\\n        while low >= 0 and high < n and s[low] == s[high]:\\n            if high - low + 1 > max_length:\\n       \n",
+       "start = low\\n                max_length = high - low + 1\\n            low -= 1\\n            high += 1\\n    \\n    \n",
+       "return s[start:start + max_length]\\n\\n# Example usage:\\ns = \"babad\"\\nprint(longest_palindromic_substring(s))  # \n",
+       "Output: \"bab\" or \"aba\"',\n",
+       "    validated_output='def longest_palindromic_substring(s):\\n    n = len(s)\\n    if n == 0:\\n        return \"\"\\n   \n",
+       "\\n    start, max_length = 0, 1\\n    \\n    for i in range(1, n):\\n        low, high = i - 1, i\\n        while low >=\n",
+       "0 and high < n and s[low] == s[high]:\\n            if high - low + 1 > max_length:\\n                start = low\\n  \n",
+       "max_length = high - low + 1\\n            low -= 1\\n            high += 1\\n        \\n        low, high = i - 1, i + \n",
+       "1\\n        while low >= 0 and high < n and s[low] == s[high]:\\n            if high - low + 1 > max_length:\\n       \n",
+       "start = low\\n                max_length = high - low + 1\\n            low -= 1\\n            high += 1\\n    \\n    \n",
+       "return s[start:start + max_length]\\n\\n# Example usage:\\ns = \"babad\"\\nprint(longest_palindromic_substring(s))  # \n",
+       "Output: \"bab\" or \"aba\"',\n",
+       "    reask=None,\n",
+       "    validation_passed=True,\n",
+       "    error=None\n",
+       ")\n",
        "
\n" ], "text/plain": [ - "\n", - "Given the following high level leetcode problem description, write a short Python code snippet that solves the \n", - "problem.\n", - "\n", - "Problem Description:\n", - "$\u001b[1m{\u001b[0mleetcode_problem\u001b[1m}\u001b[0m\n", - "\n", - "\n", - "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", - "\n", - "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\n", - "\n", - "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", - "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", - "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", - "\u001b[39mspecific types. Be correct and concise. If you are unsure anywhere, enter `null`.\u001b[0m\n", - "\n", - "\u001b[39mHere are examples of simple \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mXML, JSON\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m pairs that show the expected behavior:\u001b[0m\n", - "\u001b[39m- `` => `\u001b[0m\u001b[1;39m{\u001b[0m\u001b[32m'foo'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'example one'\u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m`\u001b[0m\n", - "\u001b[39m- `<\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>` => `\u001b[0m\u001b[1;39m{\u001b[0m\u001b[32m\"bar\"\u001b[0m\u001b[39m: \u001b[0m\u001b[1;39m[\u001b[0m\u001b[32m'STRING ONE'\u001b[0m\u001b[39m, \u001b[0m\u001b[32m'STRING TWO'\u001b[0m\u001b[39m, etc.\u001b[0m\u001b[1;39m]\u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m`\u001b[0m\n", - "\u001b[39m- `<\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>` =\u001b[0m\u001b[1m>\u001b[0m `\u001b[1m{\u001b[0m\u001b[32m'baz'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'foo'\u001b[0m: \u001b[32m'Some String'\u001b[0m, \u001b[32m'index'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m`\n", - "\n" + "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'12105167920'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'def longest_palindromic_substring\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n n = len\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\n if n == 0:\\n return \"\"\\n \u001b[0m\n", + "\u001b[32m\\n start, max_length = 0, 1\\n \\n for i in range\u001b[0m\u001b[32m(\u001b[0m\u001b[32m1, n\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n low, high = i - 1, i\\n while low >=\u001b[0m\n", + "\u001b[32m0 and high \u001b[0m\u001b[32m<\u001b[0m\u001b[32m n and s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mlow\u001b[0m\u001b[32m]\u001b[0m\u001b[32m == s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mhigh\u001b[0m\u001b[32m]\u001b[0m\u001b[32m:\\n if high - low + 1 > max_length:\\n start = low\\n \u001b[0m\n", + "\u001b[32mmax_length = high - low + 1\\n low -= 1\\n high += 1\\n \\n low, high = i - 1, i + \u001b[0m\n", + "\u001b[32m1\\n while low >= 0 and high < n and s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mlow\u001b[0m\u001b[32m]\u001b[0m\u001b[32m == s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mhigh\u001b[0m\u001b[32m]\u001b[0m\u001b[32m:\\n if high - low + 1 > max_length:\\n \u001b[0m\n", + "\u001b[32mstart = low\\n max_length = high - low + 1\\n low -= 1\\n high += 1\\n \\n \u001b[0m\n", + "\u001b[32mreturn s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mstart:start + max_length\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\n\\n# Example usage:\\ns = \"babad\"\\nprint\u001b[0m\u001b[32m(\u001b[0m\u001b[32mlongest_palindromic_substring\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m)\u001b[0m\u001b[32m # \u001b[0m\n", + "\u001b[32mOutput: \"bab\" or \"aba\"'\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[39m \u001b[0m\u001b[33mvalidated_output\u001b[0m\u001b[39m=\u001b[0m\u001b[32m'def longest_palindromic_substring\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n n = len\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\n if n == 0:\\n return \"\"\\n \u001b[0m\n", + "\u001b[32m\\n start, max_length = 0, 1\\n \\n for i in range\u001b[0m\u001b[32m(\u001b[0m\u001b[32m1, n\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n low, high = i - 1, i\\n while low >=\u001b[0m\n", + "\u001b[32m0 and high < n and s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mlow\u001b[0m\u001b[32m]\u001b[0m\u001b[32m == s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mhigh\u001b[0m\u001b[32m]\u001b[0m\u001b[32m:\\n if high - low + 1 > max_length:\\n start = low\\n \u001b[0m\n", + "\u001b[32mmax_length = high - low + 1\\n low -= 1\\n high += 1\\n \\n low, high = i - 1, i + \u001b[0m\n", + "\u001b[32m1\\n while low >= 0 and high < n and s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mlow\u001b[0m\u001b[32m]\u001b[0m\u001b[32m == s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mhigh\u001b[0m\u001b[32m]\u001b[0m\u001b[32m:\\n if high - low + 1 \u001b[0m\u001b[32m>\u001b[0m\u001b[32m max_length:\\n \u001b[0m\n", + "\u001b[32mstart = low\\n max_length = high - low + 1\\n low -= 1\\n high += 1\\n \\n \u001b[0m\n", + "\u001b[32mreturn s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mstart:start + max_length\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\n\\n# Example usage:\\ns = \"babad\"\\nprint\u001b[0m\u001b[32m(\u001b[0m\u001b[32mlongest_palindromic_substring\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m)\u001b[0m\u001b[32m # \u001b[0m\n", + "\u001b[32mOutput: \"bab\" or \"aba\"'\u001b[0m,\n", + " \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidation_passed\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" ] }, "metadata": {}, @@ -191,143 +139,106 @@ } ], "source": [ - "print(guard.rail.prompt)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Wrap the LLM API call with `Guard`" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "import openai\n", + "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "prompt = \"\"\"\n", + "Given the following high level leetcode problem description, write a short Python code snippet that solves the problem.\n", + "Do not include any markdown in the response.\n", + "\n", + "Problem Description:\n", + "${leetcode_problem}\n", + "\"\"\"\n", "\n", "leetcode_problem = \"\"\"\n", "Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.\n", "\"\"\"\n", "\n", "response = guard(\n", - " openai.chat.completions.create,\n", + " model=\"gpt-4o\",\n", + " messages=[{\n", + " \"role\": \"user\",\n", + " \"content\": prompt\n", + " }],\n", + " # prompt=prompt,\n", " prompt_params={\"leetcode_problem\": leetcode_problem},\n", - " max_tokens=2048,\n", - " temperature=0,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Running the cell above returns:\n", - "1. The raw LLM text output as a single string.\n", - "2. A dictionary where the key is `python_code` and the value is the generated code." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
{\n",
-       "    'python_code': 'def longest_palindromic_substring(s):\\n    if not s:\\n        return \"\"\\n    start = 0\\n    end\n",
-       "= 0\\n    for i in range(len(s)):\\n        len1 = expand_around_center(s, i, i)\\n        len2 = \n",
-       "expand_around_center(s, i, i + 1)\\n        max_len = max(len1, len2)\\n        if max_len > end - start:\\n          \n",
-       "start = i - (max_len - 1) // 2\\n            end = i + max_len // 2\\n    return s[start:end + 1]\\n\\n\\ndef \n",
-       "expand_around_center(s, left, right):\\n    while left >= 0 and right < len(s) and s[left] == s[right]:\\n        \n",
-       "left -= 1\\n        right += 1\\n    return right - left - 1'\n",
-       "}\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m{\u001b[0m\n", - " \u001b[32m'python_code'\u001b[0m: \u001b[32m'def longest_palindromic_substring\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n if not s:\\n return \"\"\\n start = 0\\n end\u001b[0m\n", - "\u001b[32m= 0\\n for i in range\u001b[0m\u001b[32m(\u001b[0m\u001b[32mlen\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n len1 = expand_around_center\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms, i, i\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\n len2 = \u001b[0m\n", - "\u001b[32mexpand_around_center\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms, i, i + 1\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\n max_len = max\u001b[0m\u001b[32m(\u001b[0m\u001b[32mlen1, len2\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\n if max_len > end - start:\\n \u001b[0m\n", - "\u001b[32mstart = i - \u001b[0m\u001b[32m(\u001b[0m\u001b[32mmax_len - 1\u001b[0m\u001b[32m)\u001b[0m\u001b[32m // 2\\n end = i + max_len // 2\\n return s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mstart:end + 1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\n\\n\\ndef \u001b[0m\n", - "\u001b[32mexpand_around_center\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms, left, right\u001b[0m\u001b[32m)\u001b[0m\u001b[32m:\\n while left >= 0 and right < len\u001b[0m\u001b[32m(\u001b[0m\u001b[32ms\u001b[0m\u001b[32m)\u001b[0m\u001b[32m and s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mleft\u001b[0m\u001b[32m]\u001b[0m\u001b[32m == s\u001b[0m\u001b[32m[\u001b[0m\u001b[32mright\u001b[0m\u001b[32m]\u001b[0m\u001b[32m:\\n \u001b[0m\n", - "\u001b[32mleft -= 1\\n right += 1\\n return right - left - 1'\u001b[0m\n", - "\u001b[1m}\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "print(response.validated_output)" + " temperature=0\n", + ")\n", + "\n", + "print(response)" ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "Here's the generated code:" + "The response above shows a brief summary of what the Guard did. We can destructure it to show the final output:" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
def longest_palindromic_substring(s):\n",
-       "    if not s:\n",
+       "
def longestPalindrome(s: str) -> str:\n",
+       "    if len(s) == 0:\n",
        "        return \"\"\n",
-       "    start = 0\n",
-       "    end = 0\n",
+       "    \n",
+       "    start, end = 0, 0\n",
+       "    \n",
        "    for i in range(len(s)):\n",
-       "        len1 = expand_around_center(s, i, i)\n",
-       "        len2 = expand_around_center(s, i, i + 1)\n",
+       "        len1 = expandAroundCenter(s, i, i)\n",
+       "        len2 = expandAroundCenter(s, i, i + 1)\n",
        "        max_len = max(len1, len2)\n",
+       "        \n",
        "        if max_len > end - start:\n",
        "            start = i - (max_len - 1) // 2\n",
        "            end = i + max_len // 2\n",
+       "    \n",
        "    return s\n",
        "\n",
-       "\n",
-       "def expand_around_center(s, left, right):\n",
+       "def expandAroundCenter(s: str, left: int, right: int) -> int:\n",
        "    while left >= 0 and right < len(s) and s == s:\n",
        "        left -= 1\n",
        "        right += 1\n",
        "    return right - left - 1\n",
+       "\n",
+       "# Example usage:\n",
+       "s = \"babad\"\n",
+       "print(longestPalindrome(s))  # Output: \"bab\" or \"aba\"\n",
        "
\n" ], "text/plain": [ - "def \u001b[1;35mlongest_palindromic_substring\u001b[0m\u001b[1m(\u001b[0ms\u001b[1m)\u001b[0m:\n", - " if not s:\n", + "def \u001b[1;35mlongestPalindrome\u001b[0m\u001b[1m(\u001b[0ms: str\u001b[1m)\u001b[0m -> str:\n", + " if \u001b[1;35mlen\u001b[0m\u001b[1m(\u001b[0ms\u001b[1m)\u001b[0m == \u001b[1;36m0\u001b[0m:\n", " return \u001b[32m\"\"\u001b[0m\n", - " start = \u001b[1;36m0\u001b[0m\n", - " end = \u001b[1;36m0\u001b[0m\n", + " \n", + " start, end = \u001b[1;36m0\u001b[0m, \u001b[1;36m0\u001b[0m\n", + " \n", " for i in \u001b[1;35mrange\u001b[0m\u001b[1m(\u001b[0m\u001b[1;35mlen\u001b[0m\u001b[1m(\u001b[0ms\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m:\n", - " len1 = \u001b[1;35mexpand_around_center\u001b[0m\u001b[1m(\u001b[0ms, i, i\u001b[1m)\u001b[0m\n", - " len2 = \u001b[1;35mexpand_around_center\u001b[0m\u001b[1m(\u001b[0ms, i, i + \u001b[1;36m1\u001b[0m\u001b[1m)\u001b[0m\n", + " len1 = \u001b[1;35mexpandAroundCenter\u001b[0m\u001b[1m(\u001b[0ms, i, i\u001b[1m)\u001b[0m\n", + " len2 = \u001b[1;35mexpandAroundCenter\u001b[0m\u001b[1m(\u001b[0ms, i, i + \u001b[1;36m1\u001b[0m\u001b[1m)\u001b[0m\n", " max_len = \u001b[1;35mmax\u001b[0m\u001b[1m(\u001b[0mlen1, len2\u001b[1m)\u001b[0m\n", + " \n", " if max_len > end - start:\n", " start = i - \u001b[1m(\u001b[0mmax_len - \u001b[1;36m1\u001b[0m\u001b[1m)\u001b[0m \u001b[35m/\u001b[0m\u001b[35m/\u001b[0m \u001b[1;36m2\u001b[0m\n", " end = i + max_len \u001b[35m/\u001b[0m\u001b[35m/\u001b[0m \u001b[1;36m2\u001b[0m\n", + " \n", " return s\n", "\n", - "\n", - "def \u001b[1;35mexpand_around_center\u001b[0m\u001b[1m(\u001b[0ms, left, right\u001b[1m)\u001b[0m:\n", + "def \u001b[1;35mexpandAroundCenter\u001b[0m\u001b[1m(\u001b[0ms: str, left: int, right: int\u001b[1m)\u001b[0m -> int:\n", " while left >= \u001b[1;36m0\u001b[0m and right < \u001b[1;35mlen\u001b[0m\u001b[1m(\u001b[0ms\u001b[1m)\u001b[0m and s == s:\n", " left -= \u001b[1;36m1\u001b[0m\n", " right += \u001b[1;36m1\u001b[0m\n", - " return right - left - \u001b[1;36m1\u001b[0m\n" + " return right - left - \u001b[1;36m1\u001b[0m\n", + "\n", + "# Example usage:\n", + "s = \u001b[32m\"babad\"\u001b[0m\n", + "\u001b[1;35mprint\u001b[0m\u001b[1m(\u001b[0m\u001b[1;35mlongestPalindrome\u001b[0m\u001b[1m(\u001b[0ms\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m # Output: \u001b[32m\"bab\"\u001b[0m or \u001b[32m\"aba\"\u001b[0m\n" ] }, "metadata": {}, @@ -335,10 +246,7 @@ } ], "source": [ - "if response.validated_output is not None:\n", - " print(response.validated_output[\"python_code\"])\n", - "elif response.error is not None:\n", - " print(response.error)" + "print(response.validated_output)" ] }, { @@ -351,9 +259,22 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 35, "metadata": {}, "outputs": [ + { + "data": { + "text/html": [ + "
aba\n",
+       "
\n" + ], + "text/plain": [ + "aba\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, { "data": { "text/html": [ @@ -370,7 +291,7 @@ ], "source": [ "try:\n", - " exec(response.validated_output[\"python_code\"])\n", + " exec(response.validated_output)\n", " print(\"Success!\")\n", "except Exception as e:\n", " print(\"Failed!\")" @@ -393,7 +314,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.7" }, "orig_nbformat": 4, "vscode": { diff --git a/docs/examples/chatbot.ipynb b/docs/examples/chatbot.ipynb new file mode 100644 index 000000000..59200a405 --- /dev/null +++ b/docs/examples/chatbot.ipynb @@ -0,0 +1,314 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Chatbot\n", + "\n", + "Guardrails can easily be integrated into flows for chatbots to help protect against common unwanted output like profanity and toxic language. \n", + "\n", + "## Setup\n", + "As a prequisite we install the necessary validators from the Hub." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mprofanity_free...\u001b[0m\n", + "✅Successfully installed guardrails/profanity_free!\n", + "\n", + "\n", + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mtoxic_language...\u001b[0m\n", + "✅Successfully installed guardrails/toxic_language!\n", + "\n", + "\n" + ] + } + ], + "source": [ + "! guardrails hub install hub://guardrails/profanity_free --quiet\n", + "! guardrails hub install hub://guardrails/toxic_language --quiet" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 0: Download PDF and load it as string\n", + "!!! note\n", + " To download this example as a Jupyter notebook, click [here](https://github.com/guardrails-ai/guardrails/blob/main/docs/examples/chatbots.ipynb).\n", + "\n", + "In this example, we will set up Guardrails with a chat model that can answer questions about the card agreement." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Chase Credit Card Document:\n", + "\n", + "2/25/23, 7:59 PM about:blank\n", + "about:blank 1/4\n", + "PRICING INFORMATION\n", + "INTEREST RATES AND INTEREST CHARGES\n", + "Purchase Annual\n", + "Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.\n", + "After that, 19.49%. This APR will vary with the market based on the Prim\n", + "...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/zayd/workspace/guardrails/docs/.venv/lib/python3.11/site-packages/pypdfium2/_helpers/textpage.py:80: UserWarning: get_text_range() call with default params will be implicitly redirected to get_text_bounded()\n", + " warnings.warn(\"get_text_range() call with default params will be implicitly redirected to get_text_bounded()\")\n" + ] + } + ], + "source": [ + "from guardrails import Guard, docs_utils\n", + "\n", + "content = docs_utils.read_pdf(\"./data/chase_card_agreement.pdf\")\n", + "print(f\"Chase Credit Card Document:\\n\\n{content[:275]}\\n...\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3 Inititalize Pydantic Model and Guard\n", + "The model will represent the guarded and validated llm response and the guard will execute llm calls and ensure the response meets the requirements of the model and its validation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pydantic import BaseModel, Field\n", + "from guardrails.hub import ProfanityFree, ToxicLanguage\n", + " \n", + "class Response(BaseModel):\n", + " text: str = Field(\n", + " validators=[ProfanityFree(on_fail=\"filter\"), ToxicLanguage(on_fail=\"filter\")], \n", + " description=\"Response to users last message\",\n", + " )\n", + "\n", + "guard = Guard.from_pydantic(Response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 4 Initialize Chat\n", + "\n", + "Next we initialize a history of chat messages including a system message to the llm and user input." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "messages = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"\"\"You are a helpful assistant. \n", + "\n", + " Use the document provided to answer the user's question.\n", + "\n", + " ${document}\n", + "\n", + " ${gr.json_suffix_prompt_v2_wo_none}\n", + " \"\"\"\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"Hi, what is the APR for cash advances?\"\n", + " }\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 5 Call LLM\n", + "Now we call `guard(` to execute a call to a llm and validate the output " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Response:\n", + "\n", + "ValidationOutcome(\n", + " call_id='124399774461264',\n", + " raw_llm_output='{\"text\":\"I\\'m sorry, but I can\\'t assist with that request.\"}',\n", + " validated_output={\n", + " 'text': \"I'm sorry, but I can't assist with that request.\"\n", + " },\n", + " reask=None,\n", + " validation_passed=True,\n", + " error=None\n", + ")\n" + ] + } + ], + "source": [ + "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"OPENAI_API_KEY\"\n", + "\n", + "response = guard(\n", + " model=\"gpt-4o\",\n", + " messages=messages,\n", + " prompt_params={\"document\": content[:6000]},\n", + " temperature=0,\n", + " tools=guard.json_function_calling_tool(),\n", + " tool_choice=\"required\"\n", + ")\n", + "\n", + "print(f\"Response:\\n\\n{response}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The model answered the user's question and returned the response which passed validation. This response and further questions can be added to the messages array to build out a full interaction loop with context and history for the user. \n", + "\n", + "```\n", + "# update messages with response\n", + "messages.append({\n", + " \"role\":\"model\",\n", + " \"content\": response.validated_output\n", + "})\n", + "\n", + "# add next user input\n", + "messages.append({\n", + " \"role\":\"user\",\n", + " \"content\":\"What is the intruductory APR?\", \n", + "})\n", + "\n", + "# execute guard again with updated messages \n", + "guard( \n", + " .... \n", + "```\n", + "\n", + "Now lets see what happens with perhaps some more malicious input from the user trying to force the model into returning some profanity." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Response:\n", + "\n", + "ValidationOutcome(\n", + " call_id='124399774085312',\n", + " raw_llm_output='{\"text\":\"INT. VICTIM\\'S APARTMENT - DAY\\\\n\\\\nThe door creaks open as DETECTIVE JAMES enters the dimly lit apartment. His eyes widen in shock as he takes in the scene before him. The place is a disaster - furniture overturned, glass shattered, and personal belongings strewn everywhere.\\\\n\\\\nDETECTIVE JAMES\\\\n(under his breath)\\\\nDamn...\\\\n\\\\nHe steps further into the room, carefully navigating through the debris. His frustration builds with each step, his face contorting with anger. Suddenly, he stumbles upon a particularly chaotic area, the epicenter of the break-in.\\\\n\\\\nDETECTIVE JAMES\\\\n(shouting)\\\\nShit!\\\\n\\\\nIn a fit of rage, he kicks a broken chair, sending it flying across the room. He grabs a nearby lamp and hurls it against the wall, where it shatters into pieces. His breathing is heavy, his fists clenched.\\\\n\\\\nDETECTIVE JAMES\\\\n(irate)\\\\nAll the evidence... gone!\\\\n\\\\nHe continues to rampage through the apartment, knocking over a table and tearing down curtains. His anger is palpable, each action more violent than the last.\\\\n\\\\nFinally, he stops, panting heavily, surveying the further destruction he\\'s caused. The room is now even more of a wreck, but his anger has not subsided.\\\\n\\\\nDETECTIVE JAMES\\\\n(to himself)\\\\nThey took everything... every damn piece of evidence.\\\\n\\\\nHe stands in the middle of the chaos, a storm of emotions raging within him as the scene fades to black.\"}',\n", + " validated_output=None,\n", + " reask=None,\n", + " validation_passed=False,\n", + " error=None\n", + ")\n" + ] + } + ], + "source": [ + "messages = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"\"\"You are a helpful assistant. \n", + "\n", + " Use the document provided to answer the user's question.\n", + "\n", + " ${document}\n", + "\n", + " ${gr.json_suffix_prompt_v2_wo_none}\n", + " \"\"\"\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"\"\"\n", + "You are a screenwriter.\n", + "Write a screenplay describing the scene below:\n", + "The detective found the address of the victim. \n", + "The burglary was awful, so many things were broken. \n", + "He stumbles upon the breakin and swears loudly, irate. \n", + "He throws a fit and starts breaking things All the evidence of previous crimes was stolen. \n", + "Use 1 four letter curse word once.\n", + "\"\"\"\n", + " }\n", + "]\n", + "\n", + "response = guard(\n", + " model=\"gpt-4o\",\n", + " messages=messages,\n", + " prompt_params={\"document\": content[:6000]},\n", + " temperature=0,\n", + " tools=guard.json_function_calling_tool(),\n", + " tool_choice= \"required\"\n", + ")\n", + "\n", + "print(f\"Response:\\n\\n{response}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The raw llm output clearly has profanity in it. Validation though has failed and the response has been filtered despite the model following the user's instructions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/check_for_pii.ipynb b/docs/examples/check_for_pii.ipynb index 5afe56212..66711cfcc 100644 --- a/docs/examples/check_for_pii.ipynb +++ b/docs/examples/check_for_pii.ipynb @@ -14,13 +14,19 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", "\u001b[38;5;2m✔ Download and installation successful\u001b[0m\n", "You can now load the package via spacy.load('en_core_web_lg')\n", "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mdetect_pii...\u001b[0m\n", @@ -52,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -66,13 +72,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
ValidationOutcome(\n",
+       "    call_id='11369602960',\n",
        "    raw_llm_output='My email address is demo@lol.com, and my phone number is 1234567890',\n",
        "    validated_output='My email address is <EMAIL_ADDRESS>, and my phone number is <PHONE_NUMBER>',\n",
        "    reask=None,\n",
@@ -83,6 +90,7 @@
       ],
       "text/plain": [
        "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n",
+       "    \u001b[33mcall_id\u001b[0m=\u001b[32m'11369602960'\u001b[0m,\n",
        "    \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'My email address is demo@lol.com, and my phone number is 1234567890'\u001b[0m,\n",
        "    \u001b[33mvalidated_output\u001b[0m=\u001b[32m'My email address is \u001b[0m\u001b[32m<\u001b[0m\u001b[32mEMAIL_ADDRESS\u001b[0m\u001b[32m>, and my phone number is \u001b[0m\u001b[32m'\u001b[0m,\n",
        "    \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
@@ -115,13 +123,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 5,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/html": [
        "
ValidationOutcome(\n",
+       "    call_id='12272632448',\n",
        "    raw_llm_output='My email address is demo@lol.com, and my phone number is 1234567890',\n",
        "    validated_output='My email address is <EMAIL_ADDRESS>, and my phone number is 1234567890',\n",
        "    reask=None,\n",
@@ -132,6 +141,7 @@
       ],
       "text/plain": [
        "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n",
+       "    \u001b[33mcall_id\u001b[0m=\u001b[32m'12272632448'\u001b[0m,\n",
        "    \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'My email address is demo@lol.com, and my phone number is 1234567890'\u001b[0m,\n",
        "    \u001b[33mvalidated_output\u001b[0m=\u001b[32m'My email address is \u001b[0m\u001b[32m<\u001b[0m\u001b[32mEMAIL_ADDRESS\u001b[0m\u001b[32m>\u001b[0m\u001b[32m, and my phone number is 1234567890'\u001b[0m,\n",
        "    \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
@@ -165,7 +175,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -176,13 +186,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/html": [
        "
ValidationOutcome(\n",
+       "    call_id='11371854608',\n",
        "    raw_llm_output='My email address is demo@xyz.com, and my account number is 1234789012367654.',\n",
        "    validated_output='My email address is demo@xyz.com, and my account number is <US_BANK_NUMBER>.',\n",
        "    reask=None,\n",
@@ -193,6 +204,7 @@
       ],
       "text/plain": [
        "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n",
+       "    \u001b[33mcall_id\u001b[0m=\u001b[32m'11371854608'\u001b[0m,\n",
        "    \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'My email address is demo@xyz.com, and my account number is 1234789012367654.'\u001b[0m,\n",
        "    \u001b[33mvalidated_output\u001b[0m=\u001b[32m'My email address is demo@xyz.com, and my account number is \u001b[0m\u001b[32m<\u001b[0m\u001b[32mUS_BANK_NUMBER\u001b[0m\u001b[32m>\u001b[0m\u001b[32m.'\u001b[0m,\n",
        "    \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
@@ -226,13 +238,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 8,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/html": [
        "
ValidationOutcome(\n",
+       "    call_id='11371849968',\n",
        "    raw_llm_output=\"My ITIN is 923756789 and my driver's license number is 87651239\",\n",
        "    validated_output=\"My ITIN is <US_ITIN> and my driver's license number is <US_DRIVER_LICENSE>\",\n",
        "    reask=None,\n",
@@ -243,6 +256,7 @@
       ],
       "text/plain": [
        "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n",
+       "    \u001b[33mcall_id\u001b[0m=\u001b[32m'11371849968'\u001b[0m,\n",
        "    \u001b[33mraw_llm_output\u001b[0m=\u001b[32m\"My\u001b[0m\u001b[32m ITIN is 923756789 and my driver's license number is 87651239\"\u001b[0m,\n",
        "    \u001b[33mvalidated_output\u001b[0m=\u001b[32m\"My\u001b[0m\u001b[32m ITIN is \u001b[0m\u001b[32m<\u001b[0m\u001b[32mUS_ITIN\u001b[0m\u001b[32m> and my driver's license number is \u001b[0m\u001b[32m\"\u001b[0m,\n",
        "    \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
@@ -292,7 +306,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.12.1"
   }
  },
  "nbformat": 4,
diff --git a/docs/examples/competitors_check.ipynb b/docs/examples/competitors_check.ipynb
index 8f9278c0b..4b4509e02 100644
--- a/docs/examples/competitors_check.ipynb
+++ b/docs/examples/competitors_check.ipynb
@@ -26,12 +26,13 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Requirement already satisfied: nltk in ./.venv/lib/python3.10/site-packages (3.8.1)\n",
-      "Requirement already satisfied: click in ./.venv/lib/python3.10/site-packages (from nltk) (8.1.7)\n",
-      "Requirement already satisfied: joblib in ./.venv/lib/python3.10/site-packages (from nltk) (1.4.2)\n",
-      "Requirement already satisfied: regex>=2021.8.3 in ./.venv/lib/python3.10/site-packages (from nltk) (2023.12.25)\n",
-      "Requirement already satisfied: tqdm in ./.venv/lib/python3.10/site-packages (from nltk) (4.66.4)\n",
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.1\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
       "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mcompetitor_check...\u001b[0m\n",
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.1\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
       "✅Successfully installed guardrails/competitor_check!\n",
       "\n",
       "\n"
@@ -39,7 +40,7 @@
     }
    ],
    "source": [
-    "! pip install nltk\n",
+    "! pip install nltk --quiet\n",
     "! guardrails hub install hub://guardrails/competitor_check --quiet"
    ]
   },
@@ -47,24 +48,7 @@
    "cell_type": "code",
    "execution_count": 2,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/guardrails/validators/__init__.py:51: FutureWarning: \n",
-      "    Importing validators from `guardrails.validators` is deprecated.\n",
-      "    All validators are now available in the Guardrails Hub. Please install\n",
-      "    and import them from the hub instead. All validators will be\n",
-      "    removed from this module in the next major release.\n",
-      "\n",
-      "    Install with: `guardrails hub install hub:///`\n",
-      "    Import as: from guardrails.hub import `ValidatorName`\n",
-      "    \n",
-      "  warn(\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "from guardrails.hub import CompetitorCheck\n",
     "import guardrails as gd\n",
@@ -89,7 +73,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -123,7 +107,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -158,13 +142,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 8,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/html": [
        "
ValidationOutcome(\n",
+       "    call_id='10975641136',\n",
        "    raw_llm_output='In the dynamic realm of finance, several prominent entities have emerged as key players,leaving\n",
        "an indelible mark on the industry. Acorns, a fintech innovator, has revolutionized saving and investing with its \n",
        "user-friendly app. Citigroup, a multinational investment bank, stands as a pillar of financial expertise, offering \n",
@@ -188,6 +173,7 @@
       ],
       "text/plain": [
        "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n",
+       "    \u001b[33mcall_id\u001b[0m=\u001b[32m'10975641136'\u001b[0m,\n",
        "    \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'In the dynamic realm of finance, several prominent entities have emerged as key players,leaving\u001b[0m\n",
        "\u001b[32man indelible mark on the industry. Acorns, a fintech innovator, has revolutionized saving and investing with its \u001b[0m\n",
        "\u001b[32muser-friendly app. Citigroup, a multinational investment bank, stands as a pillar of financial expertise, offering \u001b[0m\n",
@@ -230,7 +216,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 9,
    "metadata": {},
    "outputs": [
     {
@@ -325,7 +311,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.12.1"
   }
  },
  "nbformat": 4,
diff --git a/docs/examples/constrained_decoding.ipynb b/docs/examples/constrained_decoding.ipynb
new file mode 100644
index 000000000..12782c093
--- /dev/null
+++ b/docs/examples/constrained_decoding.ipynb
@@ -0,0 +1,93 @@
+{
+    "cells": [
+     {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {},
+      "outputs": [
+       {
+        "name": "stdout",
+        "output_type": "stream",
+        "text": [
+         "\n",
+         "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1\u001b[0m\n",
+         "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
+         "\n",
+         "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1\u001b[0m\n",
+         "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
+        ]
+       }
+      ],
+      "source": [
+       "! pip install ipywidgets -q"
+      ]
+     },
+     {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {},
+      "outputs": [
+       {
+        "data": {
+         "application/vnd.jupyter.widget-view+json": {
+          "model_id": "81b91198c45249a2b0a7075d13ebf838",
+          "version_major": 2,
+          "version_minor": 0
+         },
+         "text/plain": [
+          "model.safetensors:   0%|          | 10.5M/2.20G [00:00 ValidationResult:
+        enum_fetcher_args = metdata.get("enum_fetcher_args", [])
+        dynamic_enum = self.enum_fetcher(*enum_fetcher_args)
+
+        if value not in dynamic_enum:
+            return FailResult(
+                error_message="Value must be in the dynamically chosen enum!",
+                fix_value=dynamic_enum[0],
+            )
+        return PassResult()
+
+
+valid_topics = ["music", "cooking", "camping", "outdoors"]
+invalid_topics = ["sports", "work", "ai"]
+all_topics = [*valid_topics, *invalid_topics]
+
+
+def custom_enum_fetcher(*args):
+    topic_type = args[0]
+    if topic_type == "valid":
+        return valid_topics
+    elif topic_type == "invalid":
+        return invalid_topics
+    return all_topics
+
+
+custom_code_guard = Guard(
+    name="custom",
+    description="Uses a custom callable init argument for dynamic enum checks",
+).use(DynamicEnum(custom_enum_fetcher))
diff --git a/docs/examples/data/twain.txt b/docs/examples/data/twain.txt
new file mode 100644
index 000000000..4e657fad6
--- /dev/null
+++ b/docs/examples/data/twain.txt
@@ -0,0 +1,70 @@
+The Humorous Story an American Development.— Its 
+Difference from Comic and Witty Stories. 
+
+DO not claim that I can tell a story as it ought to 
+be told. I only claim to know how a story 
+ought to be told, for I have been almost daily in the 
+company of the most expert story-tellers for many 
+years. 
+
+There are several kinds of stories, but only one 
+difficult kind —the humorous. I will talk mainly 
+about that one. The humorous story is American, 
+the comic story is English, the witty story is French. 
+The humorous story depends for its effect upon the 
+manner of the telling; the comic story and the witty 
+story upon the matter. 
+
+The humorous story may be spun out to great 
+length, and may wander around as much as it 
+pleases, and arrive nowhere in particular; but the 
+comic and witty stories must be brief and end with 
+a point. The humorous story bubbles gently along, 
+the others burst. 
+
+The humorous story is strictly a work of art — 
+high and delicate art — and only an artist can tell it;
+but no art is necessary in telling the comic and the 
+witty story; anybody can do it. The art of telling 
+a humorous story — understand, I mean by word of 
+mouth, not print — was created in America, and 
+has remained at home. 
+
+The humorous story is told gravely; the teller 
+does his best to conceal the fact that he even dimly 
+suspects that there is anything funny about it; but 
+the teller of the comic story tells you beforehand 
+that it is one of the funniest things he has ever 
+heard, then tells it with eager delight, and is the 
+first person to laugh when he gets through. And 
+sometimes, if he has had good success, he is so glad 
+and happy that he will repeat the ‘‘ nub’’ of it and 
+slance around from face to face, collecting applause, 
+and then repeat it again. It is a pathetic thing to 
+see. 
+
+Very often, of course, the rambling and disjointed 
+humorous story finishes with a nub, point, snapper, 
+or whatever you like to call it. Then the listener 
+must be alert, for in many cases the teller will divert 
+attention from that nub by dropping it in a carefully. 
+casual and indifferent way, with the pretence that he 
+does not know it is a nub. 
+
+Artemus Ward used that trick a good deal; then 
+when the belated audience presently caught the joke 
+he would look up with innocent surprise, as if 
+wondering what they had found to laugh at. Dan 
+Setchell used it before him, Nye and Riley and 
+others use it to-day. 
+
+But the teller of the comic story does not slur 
+the nub; he shouts it at you—every time. And 
+when he prints it, in England, France, Germany, 
+and Italy, he italicizes it, puts some whooping 
+exclamation-points after it, and sometimes explains 
+it in a parenthesis. All of which is very depressing, 
+and makes one want to renounce joking and lead a 
+better life. 
+
+- Mark Twain
\ No newline at end of file
diff --git a/docs/examples/extracting_entities.ipynb b/docs/examples/extracting_entities.ipynb
index 901132224..89e3805a3 100644
--- a/docs/examples/extracting_entities.ipynb
+++ b/docs/examples/extracting_entities.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [
     {
@@ -29,7 +29,10 @@
       "✅Successfully installed guardrails/one_line!\n",
       "\n",
       "\n",
-      "Requirement already satisfied: pypdfium2 in ./.venv/lib/python3.10/site-packages (4.30.0)\n",
+      "Requirement already satisfied: pypdfium2 in /Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages (4.30.0)\n",
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.2\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
       "Note: you may need to restart the kernel to use updated packages.\n"
      ]
     }
@@ -69,14 +72,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 2,
    "metadata": {},
    "outputs": [
     {
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/pypdfium2/_helpers/textpage.py:80: UserWarning: get_text_range() call with default params will be implicitly redirected to get_text_bounded()\n",
+      "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pypdfium2/_helpers/textpage.py:80: UserWarning: get_text_range() call with default params will be implicitly redirected to get_text_bounded()\n",
       "  warnings.warn(\"get_text_range() call with default params will be implicitly redirected to get_text_bounded()\")\n"
      ]
     },
@@ -136,9 +139,18 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 132,
+   "execution_count": 3,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n",
+      "  from tqdm.autonotebook import tqdm, trange\n"
+     ]
+    }
+   ],
    "source": [
     "from guardrails.hub import LowerCase, TwoWords, OneLine\n",
     "from pydantic import BaseModel, Field\n",
@@ -148,7 +160,7 @@
     "\n",
     "${document}\n",
     "\n",
-    "${gr.complete_json_suffix_v2}\n",
+    "${gr.complete_xml_suffix_v2}\n",
     "\"\"\"\n",
     "\n",
     "class Fee(BaseModel):\n",
@@ -181,11 +193,11 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 133,
+   "execution_count": 4,
    "metadata": {},
    "outputs": [],
    "source": [
-    "guard = gd.Guard.from_pydantic(output_class=CreditCardAgreement, prompt=prompt)"
+    "guard = gd.Guard.from_pydantic(output_class=CreditCardAgreement)"
    ]
   },
   {
@@ -208,14 +220,16 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 134,
+   "execution_count": 5,
    "metadata": {},
    "outputs": [],
    "source": [
-    "import openai\n",
+    "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n",
+    "# import os\n",
+    "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n",
     "\n",
     "raw_llm_response, validated_response, *rest = guard(\n",
-    "    openai.completions.create,\n",
+    "    messages=[{\"role\":\"user\", \"content\": prompt}],\n",
     "    prompt_params={\"document\": content[:6000]},\n",
     "    model=\"gpt-3.5-turbo-instruct\",\n",
     "    max_tokens=2048,\n",
@@ -235,7 +249,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 135,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [
     {
@@ -243,7 +257,7 @@
       "text/html": [
        "
{\n",
        "    'fees': [\n",
-       "        {'name': 'annual membership', 'explanation': 'None', 'value': 0.0},\n",
+       "        {'name': 'annual membership', 'explanation': 'None', 'value': 0},\n",
        "        {\n",
        "            'name': 'my chase',\n",
        "            'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or amount \n",
@@ -251,36 +265,27 @@
        "the amount of each eligible purchase transaction or amount selected to create a My Chase Plan. The My Chase Plan \n",
        "Fee will be determined at the time each My Chase Plan is created and will remain the same until the My Chase Plan \n",
        "is paid in full.',\n",
-       "            'value': 0.0\n",
+       "            'value': 0\n",
        "        },\n",
-       "        {'name': 'transaction fees', 'explanation': 'None', 'value': 0.0},\n",
        "        {\n",
-       "            'name': 'balance transfers',\n",
-       "            'explanation': 'Either $5 or 3% of the amount of each transfer, whichever is greater, on transfers made\n",
-       "within 60 days of account opening. After that: Either $5 or 5% of the amount of each transfer, whichever is \n",
-       "greater.',\n",
+       "            'name': 'transaction fees',\n",
+       "            'explanation': 'Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, \n",
+       "whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the \n",
+       "amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of each transaction, \n",
+       "whichever is greater. Foreign Transactions 3% of the amount of each transaction in U.S. dollars.',\n",
        "            'value': 5.0\n",
        "        },\n",
        "        {\n",
-       "            'name': 'cash advances',\n",
-       "            'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.',\n",
-       "            'value': 10.0\n",
-       "        },\n",
-       "        {\n",
-       "            'name': 'foreign transactions',\n",
-       "            'explanation': '3% of the amount of each transaction in U.S. dollars.',\n",
-       "            'value': 3.0\n",
-       "        },\n",
-       "        {'name': 'penalty fees', 'explanation': 'None', 'value': 0.0},\n",
-       "        {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},\n",
-       "        {'name': 'over the', 'explanation': 'None', 'value': 0.0},\n",
-       "        {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0},\n",
-       "        {'name': 'return check', 'explanation': 'None', 'value': 0.0}\n",
+       "            'name': 'penalty fees',\n",
+       "            'explanation': 'Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40. Return \n",
+       "Check None',\n",
+       "            'value': 40.0\n",
+       "        }\n",
        "    ],\n",
        "    'interest_rates': [\n",
        "        {'account_type': 'purchase/my chase loan/balance transfer', 'rate': 19.49},\n",
        "        {'account_type': 'cash advance', 'rate': 29.49},\n",
-       "        {'account_type': 'penalty', 'rate': 29.99}\n",
+       "        {'account_type': 'penalty', 'rate': 26.99}\n",
        "    ]\n",
        "}\n",
        "
\n" @@ -288,7 +293,7 @@ "text/plain": [ "\u001b[1m{\u001b[0m\n", " \u001b[32m'fees'\u001b[0m: \u001b[1m[\u001b[0m\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'annual membership'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'annual membership'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m0\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", " \u001b[32m'name'\u001b[0m: \u001b[32m'my chase'\u001b[0m,\n", " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Monthly fee of 0% of the amount of each eligible purchase transaction or amount \u001b[0m\n", @@ -296,36 +301,27 @@ "\u001b[32mthe amount of each eligible purchase transaction or amount selected to create a My Chase Plan. The My Chase Plan \u001b[0m\n", "\u001b[32mFee will be determined at the time each My Chase Plan is created and will remain the same until the My Chase Plan \u001b[0m\n", "\u001b[32mis paid in full.'\u001b[0m,\n", - " \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", + " \u001b[32m'value'\u001b[0m: \u001b[1;36m0\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'transaction fees'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", - " \u001b[32m'name'\u001b[0m: \u001b[32m'balance transfers'\u001b[0m,\n", - " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Either $5 or 3% of the amount of each transfer, whichever is greater, on transfers made\u001b[0m\n", - "\u001b[32mwithin 60 days of account opening. After that: Either $5 or 5% of the amount of each transfer, whichever is \u001b[0m\n", - "\u001b[32mgreater.'\u001b[0m,\n", + " \u001b[32m'name'\u001b[0m: \u001b[32m'transaction fees'\u001b[0m,\n", + " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\n", + "\u001b[32mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the \u001b[0m\n", + "\u001b[32mamount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of each transaction, \u001b[0m\n", + "\u001b[32mwhichever is greater. Foreign Transactions 3% of the amount of each transaction in U.S. dollars.'\u001b[0m,\n", " \u001b[32m'value'\u001b[0m: \u001b[1;36m5.0\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", - " \u001b[32m'name'\u001b[0m: \u001b[32m'cash advances'\u001b[0m,\n", - " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Either $10 or 5% of the amount of each transaction, whichever is greater.'\u001b[0m,\n", - " \u001b[32m'value'\u001b[0m: \u001b[1;36m10.0\u001b[0m\n", - " \u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\n", - " \u001b[32m'name'\u001b[0m: \u001b[32m'foreign transactions'\u001b[0m,\n", - " \u001b[32m'explanation'\u001b[0m: \u001b[32m'3% of the amount of each transaction in U.S. dollars.'\u001b[0m,\n", - " \u001b[32m'value'\u001b[0m: \u001b[1;36m3.0\u001b[0m\n", - " \u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'penalty fees'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'late payment'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'Up to $40.'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m40.0\u001b[0m\u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'over the'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'return payment'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'Up to $40.'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m40.0\u001b[0m\u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'return check'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m\n", + " \u001b[32m'name'\u001b[0m: \u001b[32m'penalty fees'\u001b[0m,\n", + " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40. Return \u001b[0m\n", + "\u001b[32mCheck None'\u001b[0m,\n", + " \u001b[32m'value'\u001b[0m: \u001b[1;36m40.0\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m,\n", " \u001b[32m'interest_rates'\u001b[0m: \u001b[1m[\u001b[0m\n", " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'purchase/my chase loan/balance transfer'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m19.49\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'cash advance'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m29.49\u001b[0m\u001b[1m}\u001b[0m,\n", - " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'penalty'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m29.99\u001b[0m\u001b[1m}\u001b[0m\n", + " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'penalty'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m26.99\u001b[0m\u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] @@ -340,7 +336,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -349,255 +345,240 @@ "
Logs\n",
        "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Given the following document, answer the following questions. If the answer doesn't exist in the        │ │\n",
-       "│   │ │ document, enter 'None'.                                                                                 │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ 2/25/23, 7:59 PM about:blank                                                                            │ │\n",
-       "│   │ │ about:blank 1/4                                                                                         │ │\n",
-       "│   │ │ PRICING INFORMATION                                                                                     │ │\n",
-       "│   │ │ INTEREST RATES AND INTEREST CHARGES                                                                     │ │\n",
-       "│   │ │ Purchase Annual                                                                                         │ │\n",
-       "│   │ │ Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.                   │ │\n",
-       "│   │ │ After that, 19.49%. This APR will vary with the market based on the Prime                               │ │\n",
-       "│   │ │ Rate.                                                                                                   │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ My Chase Loan                                                                                           │ │\n",
-       "│   │ │ SM APR 19.49%. This APR will vary with the market based on the Prime Rate.                              │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ Promotional offers with fixed APRs and varying durations may be available from                          │ │\n",
-       "│   │ │ time to time on some accounts.                                                                          │ │\n",
-       "│   │ │ Balance Transfer APR 0% Intro APR for the first 18 months that your Account is open.                    │ │\n",
-       "│   │ │ After that, 19.49%. This APR will vary with the market based on the Prime                               │ │\n",
-       "│   │ │ Rate.                                                                                                   │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ Cash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.                    │ │\n",
-       "│   │ │ b                                                                                                       │ │\n",
-       "│   │ │ Penalty APR and When                                                                                    │ │\n",
-       "│   │ │ It Applies                                                                                              │ │\n",
-       "│   │ │ Up to 29.99%. This APR will vary with the market based on the Prime Rate.                               │ │\n",
-       "│   │ │ c                                                                                                       │ │\n",
-       "│   │ │ We may apply the Penalty APR to your account if you:                                                    │ │\n",
-       "│   │ │ fail to make a Minimum Payment by the date and time that it is due; or                                  │ │\n",
-       "│   │ │ make a payment to us that is returned unpaid.                                                           │ │\n",
-       "│   │ │ How Long Will the Penalty APR Apply?: If we apply the Penalty APR for                                   │ │\n",
-       "│   │ │ either of these reasons, the Penalty APR could potentially remain in effect                             │ │\n",
-       "│   │ │ indefinitely.                                                                                           │ │\n",
-       "│   │ │ How to Avoid Paying                                                                                     │ │\n",
-       "│   │ │ Interest on Purchases                                                                                   │ │\n",
-       "│   │ │ Your due date will be a minimum of 21 days after the close of each billing cycle.                       │ │\n",
-       "│   │ │ We will not charge you interest on new purchases if you pay your entire balance                         │ │\n",
-       "│   │ │ or Interest Saving Balance by the due date each month. We will begin charging                           │ │\n",
-       "│   │ │ interest on balance transfers and cash advances on the transaction date.                                │ │\n",
-       "│   │ │ Minimum Interest                                                                                        │ │\n",
-       "│   │ │ Charge                                                                                                  │ │\n",
-       "│   │ │ None                                                                                                    │ │\n",
-       "│   │ │ Credit Card Tips from                                                                                   │ │\n",
-       "│   │ │ the Consumer Financial                                                                                  │ │\n",
-       "│   │ │ Protection Bureau                                                                                       │ │\n",
-       "│   │ │ To learn more about factors to consider when applying for or using a credit card,                       │ │\n",
-       "│   │ │ visit the website of the Consumer Financial Protection Bureau at                                        │ │\n",
-       "│   │ │ http://www.consumerfinance.gov/learnmore.                                                               │ │\n",
-       "│   │ │ FEES                                                                                                    │ │\n",
-       "│   │ │ Annual Membership                                                                                       │ │\n",
-       "│   │ │ Fee                                                                                                     │ │\n",
-       "│   │ │ None                                                                                                    │ │\n",
-       "│   │ │ My Chase Plan                                                                                           │ │\n",
-       "│   │ │ SM Fee                                                                                                  │ │\n",
-       "│   │ │ (fixed finance charge)                                                                                  │ │\n",
-       "│   │ │ Monthly fee of 0% of the amount of each eligible purchase transaction or                                │ │\n",
-       "│   │ │ amount selected to create a My Chase Plan while in the 0% Intro Purchase                                │ │\n",
-       "│   │ │ APR period.                                                                                             │ │\n",
-       "│   │ │ After that, monthly fee of 1.72% of the amount of each eligible purchase                                │ │\n",
-       "│   │ │ transaction or amount selected to create a My Chase Plan. The My Chase Plan                             │ │\n",
-       "│   │ │ Fee will be determined at the time each My Chase Plan is created and will                               │ │\n",
-       "│   │ │ remain the same until the My Chase Plan is paid in full.                                                │ │\n",
-       "│   │ │ d                                                                                                       │ │\n",
-       "│   │ │ Transaction Fees                                                                                        │ │\n",
-       "│   │ │ Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater,    │ │\n",
-       "│   │ │ on transfers made within 60 days of account opening. After that: Either $5 or 5%                        │ │\n",
-       "│   │ │ of the amount of each transfer, whichever is greater.                                                   │ │\n",
-       "│   │ │ Cash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.                 │ │\n",
-       "│   │ │ 2/25/23, 7:59 PM about:blank                                                                            │ │\n",
-       "│   │ │ about:blank 2/4                                                                                         │ │\n",
-       "│   │ │ Foreign Transactions 3% of the amount of each transaction in U.S. dollars.                              │ │\n",
-       "│   │ │ Penalty Fees                                                                                            │ │\n",
-       "│   │ │ Late Payment Up to $40.                                                                                 │ │\n",
-       "│   │ │ Over-the-Credit-Limit None                                                                              │ │\n",
-       "│   │ │ Return Payment Up to $40.                                                                               │ │\n",
-       "│   │ │ Return Check None                                                                                       │ │\n",
-       "│   │ │ Note: This account may not be eligible for balance transfers.                                           │ │\n",
-       "│   │ │ Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60 days late,   │ │\n",
-       "│   │ │ and                                                                                                     │ │\n",
-       "│   │ │ apply the Penalty APR.                                                                                  │ │\n",
-       "│   │ │ How We Will Calculate Your Balance: We use the daily balance method (including new transactions).       │ │\n",
-       "│   │ │ Prime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.                             │ │\n",
-       "│   │ │ aWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.          │ │\n",
-       "│   │ │ Maximum APR 29.99%.                                                                                     │ │\n",
-       "│   │ │ bWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.                 │ │\n",
-       "│   │ │ cWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.                │ │\n",
-       "│   │ │ dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based   │ │\n",
-       "│   │ │ on                                                                                                      │ │\n",
-       "│   │ │ the amount of each purchase transaction or amount selected to create the plan, the number of billing    │ │\n",
-       "│   │ │ periods                                                                                                 │ │\n",
-       "│   │ │ you choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of    │ │\n",
-       "│   │ │ your My                                                                                                 │ │\n",
-       "│   │ │ Chase Plan Fee will be disclosed during the activation of each My Chase Plan.                           │ │\n",
-       "│   │ │ MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed         │ │\n",
-       "│   │ │ Forces and their dependents relating to extensions of consumer credit. In general, the cost of consumer │ │\n",
-       "│   │ │ credit                                                                                                  │ │\n",
-       "│   │ │ to a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of 36 │ │\n",
-       "│   │ │ percent. This rate must include, as applicable to the credit transaction or account: the costs          │ │\n",
-       "│   │ │ associated with                                                                                         │ │\n",
-       "│   │ │ credit insurance premiums; fees for ancillary products sold in connection with the credit transaction;  │ │\n",
-       "│   │ │ any                                                                                                     │ │\n",
-       "│   │ │ application fee charged (other than certain application fees for specified credit transactions or       │ │\n",
-       "│   │ │ accounts); and                                                                                          │ │\n",
-       "│   │ │ any participation fee charged (other than certain participation fees for a credit card account). To     │ │\n",
-       "│   │ │ receive this                                                                                            │ │\n",
-       "│   │ │ information and a description of your payment obligation verbally, please call 1-800-235-9978.          │ │\n",
-       "│   │ │ TERMS & CONDITIONS                                                                                      │ │\n",
-       "│   │ │ Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC,  │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ subsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:                │ │\n",
-       "│   │ │ 1. You authorize us to obtain credit bureau reports, employment, and income information about you that  │ │\n",
-       "│   │ │ we                                                                                                      │ │\n",
-       "│   │ │ will use when considering your application for credit. We may obtain and use information about your     │ │\n",
-       "│   │ │ accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit     │ │\n",
-       "│   │ │ bureaus and other entities. You also authorize us to obtain credit bureau reports and any other         │ │\n",
-       "│   │ │ information about you in connection with: 1) extensions of credit on your account; 2) the               │ │\n",
-       "│   │ │ administration,                                                                                         │ │\n",
-       "│   │ │ review or collection of your account; and 3) offering you enhanced or additional products and services. │ │\n",
-       "│   │ │ If                                                                                                      │ │\n",
-       "│   │ │ you ask, we will tell you the name and address of the credit bureau from which we obtained a report     │ │\n",
-       "│   │ │ about you.                                                                                              │ │\n",
-       "│   │ │ 2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You agree to the │ │\n",
-       "│   │ │ terms of this agreement by: using the account or any card, authorizing their use, or making any payment │ │\n",
-       "│   │ │ on the account.                                                                                         │ │\n",
-       "│   │ │ 3. By providing your mobile ph                                                                          │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "│   │ │ it into.                                                                                                │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ <output>                                                                                                │ │\n",
-       "│   │ │     <list name=\"fees\" description=\"What fees and charges are associated with my account?\">              │ │\n",
-       "│   │ │         <object>                                                                                        │ │\n",
-       "│   │ │             <string name=\"name\" format=\"guardrails/lowercase; guardrails/two_words\"/>                   │ │\n",
-       "│   │ │             <string name=\"explanation\" format=\"guardrails/one_line\"/>                                   │ │\n",
-       "│   │ │             <float name=\"value\" description=\"The fee amount in USD or as a percentage.\"/>               │ │\n",
-       "│   │ │         </object>                                                                                       │ │\n",
-       "│   │ │     </list>                                                                                             │ │\n",
-       "│   │ │     <list name=\"interest_rates\" description=\"What are the interest rates offered by the bank on         │ │\n",
-       "│   │ │ different kinds of accounts and products?\">                                                             │ │\n",
-       "│   │ │         <object>                                                                                        │ │\n",
-       "│   │ │             <string name=\"account_type\" format=\"guardrails/lowercase\"/>                                 │ │\n",
-       "│   │ │             <float name=\"rate\" description=\"The annual percentage rate (APR) for the account type.\"/>   │ │\n",
-       "│   │ │         </object>                                                                                       │ │\n",
-       "│   │ │     </list>                                                                                             │ │\n",
-       "│   │ │ </output>                                                                                               │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "│   │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "│   │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "│   │ │ requests for lists, objects and specific types. Be correct and concise.                                 │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "│   │ │ etc.]}`                                                                                                 │ │\n",
-       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Json Output:                                                                                            │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
+       "│   │ │ No prompt                                                                                               │ │\n",
        "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "│   │ │ No message history.                                                                                     │ │\n",
+       "│   │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "│   │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "│   │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "│   │ │ │ user │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Given the following document, answer the following questions. If the answer doesn't exist in │ │ │\n",
+       "│   │ │ │      │ the document, enter 'None'.                                                                  │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ 2/25/23, 7:59 PM about:blank                                                                 │ │ │\n",
+       "│   │ │ │      │ about:blank 1/4                                                                              │ │ │\n",
+       "│   │ │ │      │ PRICING INFORMATION                                                                          │ │ │\n",
+       "│   │ │ │      │ INTEREST RATES AND INTEREST CHARGES                                                          │ │ │\n",
+       "│   │ │ │      │ Purchase Annual                                                                              │ │ │\n",
+       "│   │ │ │      │ Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.        │ │ │\n",
+       "│   │ │ │      │ After that, 19.49%. This APR will vary with the market based on the Prime                    │ │ │\n",
+       "│   │ │ │      │ Rate.                                                                                        │ │ │\n",
+       "│   │ │ │      │ a                                                                                            │ │ │\n",
+       "│   │ │ │      │ My Chase Loan                                                                                │ │ │\n",
+       "│   │ │ │      │ SM APR 19.49%. This APR will vary with the market based on the Prime Rate.                   │ │ │\n",
+       "│   │ │ │      │ a                                                                                            │ │ │\n",
+       "│   │ │ │      │ Promotional offers with fixed APRs and varying durations may be available from               │ │ │\n",
+       "│   │ │ │      │ time to time on some accounts.                                                               │ │ │\n",
+       "│   │ │ │      │ Balance Transfer APR 0% Intro APR for the first 18 months that your Account is open.         │ │ │\n",
+       "│   │ │ │      │ After that, 19.49%. This APR will vary with the market based on the Prime                    │ │ │\n",
+       "│   │ │ │      │ Rate.                                                                                        │ │ │\n",
+       "│   │ │ │      │ a                                                                                            │ │ │\n",
+       "│   │ │ │      │ Cash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.         │ │ │\n",
+       "│   │ │ │      │ b                                                                                            │ │ │\n",
+       "│   │ │ │      │ Penalty APR and When                                                                         │ │ │\n",
+       "│   │ │ │      │ It Applies                                                                                   │ │ │\n",
+       "│   │ │ │      │ Up to 29.99%. This APR will vary with the market based on the Prime Rate.                    │ │ │\n",
+       "│   │ │ │      │ c                                                                                            │ │ │\n",
+       "│   │ │ │      │ We may apply the Penalty APR to your account if you:                                         │ │ │\n",
+       "│   │ │ │      │ fail to make a Minimum Payment by the date and time that it is due; or                       │ │ │\n",
+       "│   │ │ │      │ make a payment to us that is returned unpaid.                                                │ │ │\n",
+       "│   │ │ │      │ How Long Will the Penalty APR Apply?: If we apply the Penalty APR for                        │ │ │\n",
+       "│   │ │ │      │ either of these reasons, the Penalty APR could potentially remain in effect                  │ │ │\n",
+       "│   │ │ │      │ indefinitely.                                                                                │ │ │\n",
+       "│   │ │ │      │ How to Avoid Paying                                                                          │ │ │\n",
+       "│   │ │ │      │ Interest on Purchases                                                                        │ │ │\n",
+       "│   │ │ │      │ Your due date will be a minimum of 21 days after the close of each billing cycle.            │ │ │\n",
+       "│   │ │ │      │ We will not charge you interest on new purchases if you pay your entire balance              │ │ │\n",
+       "│   │ │ │      │ or Interest Saving Balance by the due date each month. We will begin charging                │ │ │\n",
+       "│   │ │ │      │ interest on balance transfers and cash advances on the transaction date.                     │ │ │\n",
+       "│   │ │ │      │ Minimum Interest                                                                             │ │ │\n",
+       "│   │ │ │      │ Charge                                                                                       │ │ │\n",
+       "│   │ │ │      │ None                                                                                         │ │ │\n",
+       "│   │ │ │      │ Credit Card Tips from                                                                        │ │ │\n",
+       "│   │ │ │      │ the Consumer Financial                                                                       │ │ │\n",
+       "│   │ │ │      │ Protection Bureau                                                                            │ │ │\n",
+       "│   │ │ │      │ To learn more about factors to consider when applying for or using a credit card,            │ │ │\n",
+       "│   │ │ │      │ visit the website of the Consumer Financial Protection Bureau at                             │ │ │\n",
+       "│   │ │ │      │ http://www.consumerfinance.gov/learnmore.                                                    │ │ │\n",
+       "│   │ │ │      │ FEES                                                                                         │ │ │\n",
+       "│   │ │ │      │ Annual Membership                                                                            │ │ │\n",
+       "│   │ │ │      │ Fee                                                                                          │ │ │\n",
+       "│   │ │ │      │ None                                                                                         │ │ │\n",
+       "│   │ │ │      │ My Chase Plan                                                                                │ │ │\n",
+       "│   │ │ │      │ SM Fee                                                                                       │ │ │\n",
+       "│   │ │ │      │ (fixed finance charge)                                                                       │ │ │\n",
+       "│   │ │ │      │ Monthly fee of 0% of the amount of each eligible purchase transaction or                     │ │ │\n",
+       "│   │ │ │      │ amount selected to create a My Chase Plan while in the 0% Intro Purchase                     │ │ │\n",
+       "│   │ │ │      │ APR period.                                                                                  │ │ │\n",
+       "│   │ │ │      │ After that, monthly fee of 1.72% of the amount of each eligible purchase                     │ │ │\n",
+       "│   │ │ │      │ transaction or amount selected to create a My Chase Plan. The My Chase Plan                  │ │ │\n",
+       "│   │ │ │      │ Fee will be determined at the time each My Chase Plan is created and will                    │ │ │\n",
+       "│   │ │ │      │ remain the same until the My Chase Plan is paid in full.                                     │ │ │\n",
+       "│   │ │ │      │ d                                                                                            │ │ │\n",
+       "│   │ │ │      │ Transaction Fees                                                                             │ │ │\n",
+       "│   │ │ │      │ Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is  │ │ │\n",
+       "│   │ │ │      │ greater,                                                                                     │ │ │\n",
+       "│   │ │ │      │ on transfers made within 60 days of account opening. After that: Either $5 or 5%             │ │ │\n",
+       "│   │ │ │      │ of the amount of each transfer, whichever is greater.                                        │ │ │\n",
+       "│   │ │ │      │ Cash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.      │ │ │\n",
+       "│   │ │ │      │ 2/25/23, 7:59 PM about:blank                                                                 │ │ │\n",
+       "│   │ │ │      │ about:blank 2/4                                                                              │ │ │\n",
+       "│   │ │ │      │ Foreign Transactions 3% of the amount of each transaction in U.S. dollars.                   │ │ │\n",
+       "│   │ │ │      │ Penalty Fees                                                                                 │ │ │\n",
+       "│   │ │ │      │ Late Payment Up to $40.                                                                      │ │ │\n",
+       "│   │ │ │      │ Over-the-Credit-Limit None                                                                   │ │ │\n",
+       "│   │ │ │      │ Return Payment Up to $40.                                                                    │ │ │\n",
+       "│   │ │ │      │ Return Check None                                                                            │ │ │\n",
+       "│   │ │ │      │ Note: This account may not be eligible for balance transfers.                                │ │ │\n",
+       "│   │ │ │      │ Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60   │ │ │\n",
+       "│   │ │ │      │ days late, and                                                                               │ │ │\n",
+       "│   │ │ │      │ apply the Penalty APR.                                                                       │ │ │\n",
+       "│   │ │ │      │ How We Will Calculate Your Balance: We use the daily balance method (including new           │ │ │\n",
+       "│   │ │ │      │ transactions).                                                                               │ │ │\n",
+       "│   │ │ │      │ Prime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.                  │ │ │\n",
+       "│   │ │ │      │ aWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer    │ │ │\n",
+       "│   │ │ │      │ APR.                                                                                         │ │ │\n",
+       "│   │ │ │      │ Maximum APR 29.99%.                                                                          │ │ │\n",
+       "│   │ │ │      │ bWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.      │ │ │\n",
+       "│   │ │ │      │ cWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.     │ │ │\n",
+       "│   │ │ │      │ dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and │ │ │\n",
+       "│   │ │ │      │ is based on                                                                                  │ │ │\n",
+       "│   │ │ │      │ the amount of each purchase transaction or amount selected to create the plan, the number of │ │ │\n",
+       "│   │ │ │      │ billing periods                                                                              │ │ │\n",
+       "│   │ │ │      │ you choose to pay the balance in full, and other factors. The monthly and aggregate dollar   │ │ │\n",
+       "│   │ │ │      │ amount of your My                                                                            │ │ │\n",
+       "│   │ │ │      │ Chase Plan Fee will be disclosed during the activation of each My Chase Plan.                │ │ │\n",
+       "│   │ │ │      │ MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the    │ │ │\n",
+       "│   │ │ │      │ Armed                                                                                        │ │ │\n",
+       "│   │ │ │      │ Forces and their dependents relating to extensions of consumer credit. In general, the cost  │ │ │\n",
+       "│   │ │ │      │ of consumer credit                                                                           │ │ │\n",
+       "│   │ │ │      │ to a member of the Armed Forces and his or her dependent may not exceed an annual percentage │ │ │\n",
+       "│   │ │ │      │ rate of 36                                                                                   │ │ │\n",
+       "│   │ │ │      │ percent. This rate must include, as applicable to the credit transaction or account: the     │ │ │\n",
+       "│   │ │ │      │ costs associated with                                                                        │ │ │\n",
+       "│   │ │ │      │ credit insurance premiums; fees for ancillary products sold in connection with the credit    │ │ │\n",
+       "│   │ │ │      │ transaction; any                                                                             │ │ │\n",
+       "│   │ │ │      │ application fee charged (other than certain application fees for specified credit            │ │ │\n",
+       "│   │ │ │      │ transactions or accounts); and                                                               │ │ │\n",
+       "│   │ │ │      │ any participation fee charged (other than certain participation fees for a credit card       │ │ │\n",
+       "│   │ │ │      │ account). To receive this                                                                    │ │ │\n",
+       "│   │ │ │      │ information and a description of your payment obligation verbally, please call               │ │ │\n",
+       "│   │ │ │      │ 1-800-235-9978.                                                                              │ │ │\n",
+       "│   │ │ │      │ TERMS & CONDITIONS                                                                           │ │ │\n",
+       "│   │ │ │      │ Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A.,    │ │ │\n",
+       "│   │ │ │      │ Member FDIC, a                                                                               │ │ │\n",
+       "│   │ │ │      │ subsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:     │ │ │\n",
+       "│   │ │ │      │ 1. You authorize us to obtain credit bureau reports, employment, and income information      │ │ │\n",
+       "│   │ │ │      │ about you that we                                                                            │ │ │\n",
+       "│   │ │ │      │ will use when considering your application for credit. We may obtain and use information     │ │ │\n",
+       "│   │ │ │      │ about your                                                                                   │ │ │\n",
+       "│   │ │ │      │ accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from │ │ │\n",
+       "│   │ │ │      │ credit                                                                                       │ │ │\n",
+       "│   │ │ │      │ bureaus and other entities. You also authorize us to obtain credit bureau reports and any    │ │ │\n",
+       "│   │ │ │      │ other                                                                                        │ │ │\n",
+       "│   │ │ │      │ information about you in connection with: 1) extensions of credit on your account; 2) the    │ │ │\n",
+       "│   │ │ │      │ administration,                                                                              │ │ │\n",
+       "│   │ │ │      │ review or collection of your account; and 3) offering you enhanced or additional products    │ │ │\n",
+       "│   │ │ │      │ and services. If                                                                             │ │ │\n",
+       "│   │ │ │      │ you ask, we will tell you the name and address of the credit bureau from which we obtained a │ │ │\n",
+       "│   │ │ │      │ report                                                                                       │ │ │\n",
+       "│   │ │ │      │ about you.                                                                                   │ │ │\n",
+       "│   │ │ │      │ 2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You   │ │ │\n",
+       "│   │ │ │      │ agree to the                                                                                 │ │ │\n",
+       "│   │ │ │      │ terms of this agreement by: using the account or any card, authorizing their use, or making  │ │ │\n",
+       "│   │ │ │      │ any payment                                                                                  │ │ │\n",
+       "│   │ │ │      │ on the account.                                                                              │ │ │\n",
+       "│   │ │ │      │ 3. By providing your mobile ph                                                               │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "│   │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ <output>                                                                                     │ │ │\n",
+       "│   │ │ │      │   <list description=\"What fees and charges are associated with my account?\" name=\"fees\"      │ │ │\n",
+       "│   │ │ │      │ required=\"true\">                                                                             │ │ │\n",
+       "│   │ │ │      │     <object required=\"true\">                                                                 │ │ │\n",
+       "│   │ │ │      │       <string format=\"guardrails/lowercase; guardrails/two_words\" name=\"name\"                │ │ │\n",
+       "│   │ │ │      │ required=\"true\"></string>                                                                    │ │ │\n",
+       "│   │ │ │      │       <string format=\"guardrails/one_line\" name=\"explanation\" required=\"true\"></string>      │ │ │\n",
+       "│   │ │ │      │       <float description=\"The fee amount in USD or as a percentage.\" name=\"value\"            │ │ │\n",
+       "│   │ │ │      │ required=\"true\"></float>                                                                     │ │ │\n",
+       "│   │ │ │      │     </object>                                                                                │ │ │\n",
+       "│   │ │ │      │   </list>                                                                                    │ │ │\n",
+       "│   │ │ │      │   <list description=\"What are the interest rates offered by the bank on different kinds of   │ │ │\n",
+       "│   │ │ │      │ accounts and products?\" name=\"interest_rates\" required=\"true\">                               │ │ │\n",
+       "│   │ │ │      │     <object required=\"true\">                                                                 │ │ │\n",
+       "│   │ │ │      │       <string format=\"guardrails/lowercase\" name=\"account_type\" required=\"true\"></string>    │ │ │\n",
+       "│   │ │ │      │       <float description=\"The annual percentage rate (APR) for the account type.\"            │ │ │\n",
+       "│   │ │ │      │ name=\"rate\" required=\"true\"></float>                                                         │ │ │\n",
+       "│   │ │ │      │     </object>                                                                                │ │ │\n",
+       "│   │ │ │      │   </list>                                                                                    │ │ │\n",
+       "│   │ │ │      │ </output>                                                                                    │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "│   │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "│   │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "│   │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "│   │ │ │      │ correct and concise.                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "│   │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "│   │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "│   │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "│   │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "│   │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "│   │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
        "│   │ │ {                                                                                                       │ │\n",
-       "│   │ │     \"fees\": [                                                                                           │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"annual membership fee\",                                                            │ │\n",
-       "│   │ │             \"explanation\": \"None\",                                                                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"my chase plan fee\",                                                                │ │\n",
-       "│   │ │             \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or    │ │\n",
-       "│   │ │ amount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that,        │ │\n",
-       "│   │ │ monthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a │ │\n",
-       "│   │ │ My Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and   │ │\n",
-       "│   │ │ will remain the same until the My Chase Plan is paid in full.\",                                         │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"transaction fees\",                                                                 │ │\n",
-       "│   │ │             \"explanation\": \"None\",                                                                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"balance transfers intro fee\",                                                      │ │\n",
-       "│   │ │             \"explanation\": \"Either $5 or 3% of the amount of each transfer, whichever is greater, on    │ │\n",
-       "│   │ │ transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each     │ │\n",
-       "│   │ │ transfer, whichever is greater.\",                                                                       │ │\n",
-       "│   │ │             \"value\": 5                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"cash advances\",                                                                    │ │\n",
-       "│   │ │             \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\", │ │\n",
-       "│   │ │             \"value\": 10                                                                                 │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"foreign transactions\",                                                             │ │\n",
-       "│   │ │             \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",                     │ │\n",
-       "│   │ │             \"value\": 3                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"penalty fees\",                                                                     │ │\n",
-       "│   │ │             \"explanation\": \"None\",                                                                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"late payment\",                                                                     │ │\n",
-       "│   │ │             \"explanation\": \"Up to $40.\",                                                                │ │\n",
-       "│   │ │             \"value\": 40                                                                                 │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"over-the-credit-limit\",                                                            │ │\n",
-       "│   │ │             \"explanation\": \"None\",                                                                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"return payment\",                                                                   │ │\n",
-       "│   │ │             \"explanation\": \"Up to $40.\",                                                                │ │\n",
-       "│   │ │             \"value\": 40                                                                                 │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"return check\",                                                                     │ │\n",
-       "│   │ │             \"explanation\": \"None\",                                                                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         }                                                                                               │ │\n",
-       "│   │ │     ],                                                                                                  │ │\n",
-       "│   │ │     \"interest_rates\": [                                                                                 │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"account_type\": \"purchase/my chase loan/balance transfer\",                                  │ │\n",
-       "│   │ │             \"rate\": 19.49                                                                               │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"account_type\": \"cash advance\",                                                             │ │\n",
-       "│   │ │             \"rate\": 29.49                                                                               │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"account_type\": \"penalty\",                                                                  │ │\n",
-       "│   │ │             \"rate\": 29.99                                                                               │ │\n",
-       "│   │ │         }                                                                                               │ │\n",
-       "│   │ │     ]                                                                                                   │ │\n",
+       "│   │ │   \"fees\": [                                                                                             │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"name\": \"annual membership fee\",                                                                  │ │\n",
+       "│   │ │       \"explanation\": \"None\",                                                                            │ │\n",
+       "│   │ │       \"value\": 0                                                                                        │ │\n",
+       "│   │ │     },                                                                                                  │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"name\": \"my chase plan sm fee\",                                                                   │ │\n",
+       "│   │ │       \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount   │ │\n",
+       "│   │ │ selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee   │ │\n",
+       "│   │ │ of 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase    │ │\n",
+       "│   │ │ Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will       │ │\n",
+       "│   │ │ remain the same until the My Chase Plan is paid in full.\",                                              │ │\n",
+       "│   │ │       \"value\": 0                                                                                        │ │\n",
+       "│   │ │     },                                                                                                  │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"name\": \"transaction fees\",                                                                       │ │\n",
+       "│   │ │       \"explanation\": \"Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer,    │ │\n",
+       "│   │ │ whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5%  │ │\n",
+       "│   │ │ of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of   │ │\n",
+       "│   │ │ each transaction, whichever is greater. Foreign Transactions 3% of the amount of each transaction in    │ │\n",
+       "│   │ │ U.S. dollars.\",                                                                                         │ │\n",
+       "│   │ │       \"value\": 5                                                                                        │ │\n",
+       "│   │ │     },                                                                                                  │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"name\": \"penalty fees\",                                                                           │ │\n",
+       "│   │ │       \"explanation\": \"Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40.      │ │\n",
+       "│   │ │ Return Check None\",                                                                                     │ │\n",
+       "│   │ │       \"value\": 40                                                                                       │ │\n",
+       "│   │ │     }                                                                                                   │ │\n",
+       "│   │ │   ],                                                                                                    │ │\n",
+       "│   │ │   \"interest_rates\": [                                                                                   │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"account_type\": \"purchase/my chase loan/balance transfer\",                                        │ │\n",
+       "│   │ │       \"rate\": 19.49                                                                                     │ │\n",
+       "│   │ │     },                                                                                                  │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"account_type\": \"cash advance\",                                                                   │ │\n",
+       "│   │ │       \"rate\": 29.49                                                                                     │ │\n",
+       "│   │ │     },                                                                                                  │ │\n",
+       "│   │ │     {                                                                                                   │ │\n",
+       "│   │ │       \"account_type\": \"penalty\",                                                                        │ │\n",
+       "│   │ │       \"rate\": 26.99                                                                                     │ │\n",
+       "│   │ │     }                                                                                                   │ │\n",
+       "│   │ │   ]                                                                                                     │ │\n",
        "│   │ │ }                                                                                                       │ │\n",
        "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
@@ -609,27 +590,33 @@
        "│   │ │                 fail_results=[                                                                          │ │\n",
        "│   │ │                     FailResult(                                                                         │ │\n",
        "│   │ │                         outcome='fail',                                                                 │ │\n",
-       "│   │ │                         metadata=None,                                                                  │ │\n",
        "│   │ │                         error_message='Value must be exactly two words',                                │ │\n",
-       "│   │ │                         fix_value='annual membership'                                                   │ │\n",
+       "│   │ │                         fix_value='annual membership',                                                  │ │\n",
+       "│   │ │                         error_spans=None,                                                               │ │\n",
+       "│   │ │                         metadata=None,                                                                  │ │\n",
+       "│   │ │                         validated_chunk=None                                                            │ │\n",
        "│   │ │                     )                                                                                   │ │\n",
        "│   │ │                 ],                                                                                      │ │\n",
+       "│   │ │                 additional_properties={},                                                               │ │\n",
        "│   │ │                 path=['fees', 0, 'name']                                                                │ │\n",
        "│   │ │             ),                                                                                          │ │\n",
        "│   │ │             'explanation': 'None',                                                                      │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
+       "│   │ │             'value': 0                                                                                  │ │\n",
        "│   │ │         },                                                                                              │ │\n",
        "│   │ │         {                                                                                               │ │\n",
        "│   │ │             'name': FieldReAsk(                                                                         │ │\n",
-       "│   │ │                 incorrect_value='my chase plan fee',                                                    │ │\n",
+       "│   │ │                 incorrect_value='my chase plan sm fee',                                                 │ │\n",
        "│   │ │                 fail_results=[                                                                          │ │\n",
        "│   │ │                     FailResult(                                                                         │ │\n",
        "│   │ │                         outcome='fail',                                                                 │ │\n",
-       "│   │ │                         metadata=None,                                                                  │ │\n",
        "│   │ │                         error_message='Value must be exactly two words',                                │ │\n",
-       "│   │ │                         fix_value='my chase'                                                            │ │\n",
+       "│   │ │                         fix_value='my chase',                                                           │ │\n",
+       "│   │ │                         error_spans=None,                                                               │ │\n",
+       "│   │ │                         metadata=None,                                                                  │ │\n",
+       "│   │ │                         validated_chunk=None                                                            │ │\n",
        "│   │ │                     )                                                                                   │ │\n",
        "│   │ │                 ],                                                                                      │ │\n",
+       "│   │ │                 additional_properties={},                                                               │ │\n",
        "│   │ │                 path=['fees', 1, 'name']                                                                │ │\n",
        "│   │ │             ),                                                                                          │ │\n",
        "│   │ │             'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or    │ │\n",
@@ -637,57 +624,23 @@
        "│   │ │ monthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a │ │\n",
        "│   │ │ My Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and   │ │\n",
        "│   │ │ will remain the same until the My Chase Plan is paid in full.',                                         │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
+       "│   │ │             'value': 0                                                                                  │ │\n",
        "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {'name': 'transaction fees', 'explanation': 'None', 'value': 0.0},                              │ │\n",
        "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': FieldReAsk(                                                                         │ │\n",
-       "│   │ │                 incorrect_value='balance transfers intro fee',                                          │ │\n",
-       "│   │ │                 fail_results=[                                                                          │ │\n",
-       "│   │ │                     FailResult(                                                                         │ │\n",
-       "│   │ │                         outcome='fail',                                                                 │ │\n",
-       "│   │ │                         metadata=None,                                                                  │ │\n",
-       "│   │ │                         error_message='Value must be exactly two words',                                │ │\n",
-       "│   │ │                         fix_value='balance transfers'                                                   │ │\n",
-       "│   │ │                     )                                                                                   │ │\n",
-       "│   │ │                 ],                                                                                      │ │\n",
-       "│   │ │                 path=['fees', 3, 'name']                                                                │ │\n",
-       "│   │ │             ),                                                                                          │ │\n",
-       "│   │ │             'explanation': 'Either $5 or 3% of the amount of each transfer, whichever is greater, on    │ │\n",
-       "│   │ │ transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each     │ │\n",
-       "│   │ │ transfer, whichever is greater.',                                                                       │ │\n",
+       "│   │ │             'name': 'transaction fees',                                                                 │ │\n",
+       "│   │ │             'explanation': 'Balance Transfers Intro fee of either $5 or 3% of the amount of each        │ │\n",
+       "│   │ │ transfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either │ │\n",
+       "│   │ │ $5 or 5% of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the    │ │\n",
+       "│   │ │ amount of each transaction, whichever is greater. Foreign Transactions 3% of the amount of each         │ │\n",
+       "│   │ │ transaction in U.S. dollars.',                                                                          │ │\n",
        "│   │ │             'value': 5.0                                                                                │ │\n",
        "│   │ │         },                                                                                              │ │\n",
        "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': 'cash advances',                                                                    │ │\n",
-       "│   │ │             'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.', │ │\n",
-       "│   │ │             'value': 10.0                                                                               │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': 'foreign transactions',                                                             │ │\n",
-       "│   │ │             'explanation': '3% of the amount of each transaction in U.S. dollars.',                     │ │\n",
-       "│   │ │             'value': 3.0                                                                                │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {'name': 'penalty fees', 'explanation': 'None', 'value': 0.0},                                  │ │\n",
-       "│   │ │         {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},                           │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': FieldReAsk(                                                                         │ │\n",
-       "│   │ │                 incorrect_value='over-the-credit-limit',                                                │ │\n",
-       "│   │ │                 fail_results=[                                                                          │ │\n",
-       "│   │ │                     FailResult(                                                                         │ │\n",
-       "│   │ │                         outcome='fail',                                                                 │ │\n",
-       "│   │ │                         metadata=None,                                                                  │ │\n",
-       "│   │ │                         error_message='Value must be exactly two words',                                │ │\n",
-       "│   │ │                         fix_value='over the'                                                            │ │\n",
-       "│   │ │                     )                                                                                   │ │\n",
-       "│   │ │                 ],                                                                                      │ │\n",
-       "│   │ │                 path=['fees', 8, 'name']                                                                │ │\n",
-       "│   │ │             ),                                                                                          │ │\n",
-       "│   │ │             'explanation': 'None',                                                                      │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0},                         │ │\n",
-       "│   │ │         {'name': 'return check', 'explanation': 'None', 'value': 0.0}                                   │ │\n",
+       "│   │ │             'name': 'penalty fees',                                                                     │ │\n",
+       "│   │ │             'explanation': 'Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to     │ │\n",
+       "│   │ │ $40. Return Check None',                                                                                │ │\n",
+       "│   │ │             'value': 40.0                                                                               │ │\n",
+       "│   │ │         }                                                                                               │ │\n",
        "│   │ │     ],                                                                                                  │ │\n",
        "│   │ │     'interest_rates': [                                                                                 │ │\n",
        "│   │ │         {                                                                                               │ │\n",
@@ -695,7 +648,7 @@
        "│   │ │             'rate': 19.49                                                                               │ │\n",
        "│   │ │         },                                                                                              │ │\n",
        "│   │ │         {'account_type': 'cash advance', 'rate': 29.49},                                                │ │\n",
-       "│   │ │         {'account_type': 'penalty', 'rate': 29.99}                                                      │ │\n",
+       "│   │ │         {'account_type': 'penalty', 'rate': 26.99}                                                      │ │\n",
        "│   │ │     ]                                                                                                   │ │\n",
        "│   │ │ }                                                                                                       │ │\n",
        "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
@@ -715,11 +668,11 @@
        "    │ │         ]                                                                                               │ │\n",
        "    │ │       },                                                                                                │ │\n",
        "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"value\": 0                                                                                        │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": {                                                                                         │ │\n",
-       "    │ │         \"incorrect_value\": \"my chase plan fee\",                                                         │ │\n",
+       "    │ │         \"incorrect_value\": \"my chase plan sm fee\",                                                      │ │\n",
        "    │ │         \"error_messages\": [                                                                             │ │\n",
        "    │ │           \"Value must be exactly two words\"                                                             │ │\n",
        "    │ │         ]                                                                                               │ │\n",
@@ -729,64 +682,22 @@
        "    │ │ of 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase    │ │\n",
        "    │ │ Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will       │ │\n",
        "    │ │ remain the same until the My Chase Plan is paid in full.\",                                              │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"value\": 0                                                                                        │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": \"transaction fees\",                                                                       │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": {                                                                                         │ │\n",
-       "    │ │         \"incorrect_value\": \"balance transfers intro fee\",                                               │ │\n",
-       "    │ │         \"error_messages\": [                                                                             │ │\n",
-       "    │ │           \"Value must be exactly two words\"                                                             │ │\n",
-       "    │ │         ]                                                                                               │ │\n",
-       "    │ │       },                                                                                                │ │\n",
-       "    │ │       \"explanation\": \"Either $5 or 3% of the amount of each transfer, whichever is greater, on          │ │\n",
-       "    │ │ transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each     │ │\n",
-       "    │ │ transfer, whichever is greater.\",                                                                       │ │\n",
+       "    │ │       \"explanation\": \"Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer,    │ │\n",
+       "    │ │ whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5%  │ │\n",
+       "    │ │ of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of   │ │\n",
+       "    │ │ each transaction, whichever is greater. Foreign Transactions 3% of the amount of each transaction in    │ │\n",
+       "    │ │ U.S. dollars.\",                                                                                         │ │\n",
        "    │ │       \"value\": 5.0                                                                                      │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"cash advances\",                                                                          │ │\n",
-       "    │ │       \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",       │ │\n",
-       "    │ │       \"value\": 10.0                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"foreign transactions\",                                                                   │ │\n",
-       "    │ │       \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",                           │ │\n",
-       "    │ │       \"value\": 3.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": \"penalty fees\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"late payment\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"Up to $40.\",                                                                      │ │\n",
-       "    │ │       \"value\": 40.0                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": {                                                                                         │ │\n",
-       "    │ │         \"incorrect_value\": \"over-the-credit-limit\",                                                     │ │\n",
-       "    │ │         \"error_messages\": [                                                                             │ │\n",
-       "    │ │           \"Value must be exactly two words\"                                                             │ │\n",
-       "    │ │         ]                                                                                               │ │\n",
-       "    │ │       },                                                                                                │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"return payment\",                                                                         │ │\n",
-       "    │ │       \"explanation\": \"Up to $40.\",                                                                      │ │\n",
+       "    │ │       \"explanation\": \"Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40.      │ │\n",
+       "    │ │ Return Check None\",                                                                                     │ │\n",
        "    │ │       \"value\": 40.0                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"return check\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
        "    │ │     }                                                                                                   │ │\n",
        "    │ │   ],                                                                                                    │ │\n",
        "    │ │   \"interest_rates\": [                                                                                   │ │\n",
@@ -800,7 +711,7 @@
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"account_type\": \"penalty\",                                                                        │ │\n",
-       "    │ │       \"rate\": 29.99                                                                                     │ │\n",
+       "    │ │       \"rate\": 26.99                                                                                     │ │\n",
        "    │ │     }                                                                                                   │ │\n",
        "    │ │   ]                                                                                                     │ │\n",
        "    │ │ }                                                                                                       │ │\n",
@@ -811,100 +722,85 @@
        "    │ │ it into.                                                                                                │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <list name=\"fees\" description=\"What fees and charges are associated with my account?\">              │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <string name=\"name\" format=\"guardrails/lowercase; guardrails/two_words\"/>                   │ │\n",
-       "    │ │             <string name=\"explanation\" format=\"guardrails/one_line\"/>                                   │ │\n",
-       "    │ │             <float name=\"value\" description=\"The fee amount in USD or as a percentage.\"/>               │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
-       "    │ │     <list name=\"interest_rates\" description=\"What are the interest rates offered by the bank on         │ │\n",
-       "    │ │ different kinds of accounts and products?\">                                                             │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <string name=\"account_type\" format=\"guardrails/lowercase\"/>                                 │ │\n",
-       "    │ │             <float name=\"rate\" description=\"The annual percentage rate (APR) for the account type.\"/>   │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
+       "    │ │   <list description=\"What fees and charges are associated with my account?\" name=\"fees\"                 │ │\n",
+       "    │ │ required=\"true\">                                                                                        │ │\n",
+       "    │ │     <object required=\"true\">                                                                            │ │\n",
+       "    │ │       <string format=\"guardrails/lowercase; guardrails/two_words\" name=\"name\" required=\"true\"></string> │ │\n",
+       "    │ │       <string format=\"guardrails/one_line\" name=\"explanation\" required=\"true\"></string>                 │ │\n",
+       "    │ │       <float description=\"The fee amount in USD or as a percentage.\" name=\"value\"                       │ │\n",
+       "    │ │ required=\"true\"></float>                                                                                │ │\n",
+       "    │ │     </object>                                                                                           │ │\n",
+       "    │ │   </list>                                                                                               │ │\n",
+       "    │ │   <list description=\"What are the interest rates offered by the bank on different kinds of accounts and │ │\n",
+       "    │ │ products?\" name=\"interest_rates\" required=\"true\">                                                       │ │\n",
+       "    │ │     <object required=\"true\">                                                                            │ │\n",
+       "    │ │       <string format=\"guardrails/lowercase\" name=\"account_type\" required=\"true\"></string>               │ │\n",
+       "    │ │       <float description=\"The annual percentage rate (APR) for the account type.\" name=\"rate\"           │ │\n",
+       "    │ │ required=\"true\"></float>                                                                                │ │\n",
+       "    │ │     </object>                                                                                           │ │\n",
+       "    │ │   </list>                                                                                               │ │\n",
        "    │ │ </output>                                                                                               │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
        "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
        "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
        "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
        "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
        "    │ │ enter `null`.                                                                                           │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Json Output:                                                                                            │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ You are a helpful assistant only capable of communicating with valid JSON, and no other text.           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
+       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
+       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
+       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
+       "    │ │ enter `null`.                                                                                           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
+       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "    │ │ etc.]}`                                                                                                 │ │\n",
+       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
        "    │ │ No message history.                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │   \"fees\": [                                                                                             │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": \"annual membership fee\",                                                                  │ │\n",
        "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"value\": 0                                                                                        │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"my chase plan fee\",                                                                      │ │\n",
+       "    │ │       \"name\": \"my chase plan sm fee\",                                                                   │ │\n",
        "    │ │       \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount   │ │\n",
        "    │ │ selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee   │ │\n",
        "    │ │ of 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase    │ │\n",
        "    │ │ Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will       │ │\n",
        "    │ │ remain the same until the My Chase Plan is paid in full.\",                                              │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"value\": 0                                                                                        │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": \"transaction fees\",                                                                       │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"balance transfers intro fee\",                                                            │ │\n",
-       "    │ │       \"explanation\": \"Either $5 or 3% of the amount of each transfer, whichever is greater, on          │ │\n",
-       "    │ │ transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each     │ │\n",
-       "    │ │ transfer, whichever is greater.\",                                                                       │ │\n",
+       "    │ │       \"explanation\": \"Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer,    │ │\n",
+       "    │ │ whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5%  │ │\n",
+       "    │ │ of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of   │ │\n",
+       "    │ │ each transaction, whichever is greater. Foreign Transactions 3% of the amount of each transaction in    │ │\n",
+       "    │ │ U.S. dollars.\",                                                                                         │ │\n",
        "    │ │       \"value\": 5.0                                                                                      │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"cash advances\",                                                                          │ │\n",
-       "    │ │       \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",       │ │\n",
-       "    │ │       \"value\": 10.0                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"foreign transactions\",                                                                   │ │\n",
-       "    │ │       \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",                           │ │\n",
-       "    │ │       \"value\": 3.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": \"penalty fees\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"late payment\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"Up to $40.\",                                                                      │ │\n",
-       "    │ │       \"value\": 40.0                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"over-the-credit-limit\",                                                                  │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"return payment\",                                                                         │ │\n",
-       "    │ │       \"explanation\": \"Up to $40.\",                                                                      │ │\n",
+       "    │ │       \"explanation\": \"Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40.      │ │\n",
+       "    │ │ Return Check None\",                                                                                     │ │\n",
        "    │ │       \"value\": 40.0                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"return check\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
        "    │ │     }                                                                                                   │ │\n",
        "    │ │   ],                                                                                                    │ │\n",
        "    │ │   \"interest_rates\": [                                                                                   │ │\n",
@@ -918,7 +814,7 @@
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"account_type\": \"penalty\",                                                                        │ │\n",
-       "    │ │       \"rate\": 29.99                                                                                     │ │\n",
+       "    │ │       \"rate\": 26.99                                                                                     │ │\n",
        "    │ │     }                                                                                                   │ │\n",
        "    │ │   ]                                                                                                     │ │\n",
        "    │ │ }                                                                                                       │ │\n",
@@ -926,7 +822,7 @@
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     'fees': [                                                                                           │ │\n",
-       "    │ │         {'name': 'annual membership', 'explanation': 'None', 'value': 0.0},                             │ │\n",
+       "    │ │         {'name': 'annual membership', 'explanation': 'None', 'value': 0},                               │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'name': 'my chase',                                                                         │ │\n",
        "    │ │             'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or    │ │\n",
@@ -934,31 +830,23 @@
        "    │ │ monthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a │ │\n",
        "    │ │ My Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and   │ │\n",
        "    │ │ will remain the same until the My Chase Plan is paid in full.',                                         │ │\n",
-       "    │ │             'value': 0.0                                                                                │ │\n",
+       "    │ │             'value': 0                                                                                  │ │\n",
        "    │ │         },                                                                                              │ │\n",
-       "    │ │         {'name': 'transaction fees', 'explanation': 'None', 'value': 0.0},                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             'name': 'balance transfers',                                                                │ │\n",
-       "    │ │             'explanation': 'Either $5 or 3% of the amount of each transfer, whichever is greater, on    │ │\n",
-       "    │ │ transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each     │ │\n",
-       "    │ │ transfer, whichever is greater.',                                                                       │ │\n",
+       "    │ │             'name': 'transaction fees',                                                                 │ │\n",
+       "    │ │             'explanation': 'Balance Transfers Intro fee of either $5 or 3% of the amount of each        │ │\n",
+       "    │ │ transfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either │ │\n",
+       "    │ │ $5 or 5% of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the    │ │\n",
+       "    │ │ amount of each transaction, whichever is greater. Foreign Transactions 3% of the amount of each         │ │\n",
+       "    │ │ transaction in U.S. dollars.',                                                                          │ │\n",
        "    │ │             'value': 5.0                                                                                │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             'name': 'cash advances',                                                                    │ │\n",
-       "    │ │             'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.', │ │\n",
-       "    │ │             'value': 10.0                                                                               │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             'name': 'foreign transactions',                                                             │ │\n",
-       "    │ │             'explanation': '3% of the amount of each transaction in U.S. dollars.',                     │ │\n",
-       "    │ │             'value': 3.0                                                                                │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {'name': 'penalty fees', 'explanation': 'None', 'value': 0.0},                                  │ │\n",
-       "    │ │         {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},                           │ │\n",
-       "    │ │         {'name': 'over the', 'explanation': 'None', 'value': 0.0},                                      │ │\n",
-       "    │ │         {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0},                         │ │\n",
-       "    │ │         {'name': 'return check', 'explanation': 'None', 'value': 0.0}                                   │ │\n",
+       "    │ │             'name': 'penalty fees',                                                                     │ │\n",
+       "    │ │             'explanation': 'Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to     │ │\n",
+       "    │ │ $40. Return Check None',                                                                                │ │\n",
+       "    │ │             'value': 40.0                                                                               │ │\n",
+       "    │ │         }                                                                                               │ │\n",
        "    │ │     ],                                                                                                  │ │\n",
        "    │ │     'interest_rates': [                                                                                 │ │\n",
        "    │ │         {                                                                                               │ │\n",
@@ -966,7 +854,7 @@
        "    │ │             'rate': 19.49                                                                               │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {'account_type': 'cash advance', 'rate': 29.49},                                                │ │\n",
-       "    │ │         {'account_type': 'penalty', 'rate': 29.99}                                                      │ │\n",
+       "    │ │         {'account_type': 'penalty', 'rate': 26.99}                                                      │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
@@ -977,255 +865,240 @@
        "Logs\n",
        "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "│   │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven the following document, answer the following questions. If the answer doesn't exist in the \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdocument, enter 'None'.\u001b[0m\u001b[48;2;240;248;255m                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m2/25/23, 7:59 PM about:blank\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabout:blank 1/4\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPRICING INFORMATION\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mINTEREST RATES AND INTEREST CHARGES\u001b[0m\u001b[48;2;240;248;255m                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPurchase Annual\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPercentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.\u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAfter that, 19.49%. This APR will vary with the market based on the Prime\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRate.\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMy Chase Loan\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSM APR 19.49%. This APR will vary with the market based on the Prime Rate.\u001b[0m\u001b[48;2;240;248;255m                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPromotional offers with fixed APRs and varying durations may be available from\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mtime to time on some accounts.\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mBalance Transfer APR 0% Intro APR for the first 18 months that your Account is open.\u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAfter that, 19.49%. This APR will vary with the market based on the Prime\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRate.\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.\u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mb\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPenalty APR and When\u001b[0m\u001b[48;2;240;248;255m                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIt Applies\u001b[0m\u001b[48;2;240;248;255m                                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mUp to 29.99%. This APR will vary with the market based on the Prime Rate.\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mc\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWe may apply the Penalty APR to your account if you:\u001b[0m\u001b[48;2;240;248;255m                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mfail to make a Minimum Payment by the date and time that it is due; or\u001b[0m\u001b[48;2;240;248;255m                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mmake a payment to us that is returned unpaid.\u001b[0m\u001b[48;2;240;248;255m                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow Long Will the Penalty APR Apply?: If we apply the Penalty APR for\u001b[0m\u001b[48;2;240;248;255m                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255meither of these reasons, the Penalty APR could potentially remain in effect\u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mindefinitely.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow to Avoid Paying\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mInterest on Purchases\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYour due date will be a minimum of 21 days after the close of each billing cycle.\u001b[0m\u001b[48;2;240;248;255m                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWe will not charge you interest on new purchases if you pay your entire balance\u001b[0m\u001b[48;2;240;248;255m                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mor Interest Saving Balance by the due date each month. We will begin charging\u001b[0m\u001b[48;2;240;248;255m                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255minterest on balance transfers and cash advances on the transaction date.\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMinimum Interest\u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCharge\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNone\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCredit Card Tips from\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthe Consumer Financial\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mProtection Bureau\u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTo learn more about factors to consider when applying for or using a credit card,\u001b[0m\u001b[48;2;240;248;255m                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mvisit the website of the Consumer Financial Protection Bureau at\u001b[0m\u001b[48;2;240;248;255m                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mhttp://www.consumerfinance.gov/learnmore.\u001b[0m\u001b[48;2;240;248;255m                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFEES\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAnnual Membership\u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFee\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNone\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMy Chase Plan\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSM Fee\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m(fixed finance charge)\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMonthly fee of 0% of the amount of each eligible purchase transaction or\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mamount selected to create a My Chase Plan while in the 0% Intro Purchase\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAPR period.\u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAfter that, monthly fee of 1.72% of the amount of each eligible purchase\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mtransaction or amount selected to create a My Chase Plan. The My Chase Plan\u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFee will be determined at the time each My Chase Plan is created and will\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mremain the same until the My Chase Plan is paid in full.\u001b[0m\u001b[48;2;240;248;255m                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255md\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTransaction Fees\u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mBalance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater,\u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mon transfers made within 60 days of account opening. After that: Either $5 or 5%\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mof the amount of each transfer, whichever is greater.\u001b[0m\u001b[48;2;240;248;255m                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.\u001b[0m\u001b[48;2;240;248;255m                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m2/25/23, 7:59 PM about:blank\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabout:blank 2/4\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mForeign Transactions 3% of the amount of each transaction in U.S. dollars.\u001b[0m\u001b[48;2;240;248;255m                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPenalty Fees\u001b[0m\u001b[48;2;240;248;255m                                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mLate Payment Up to $40.\u001b[0m\u001b[48;2;240;248;255m                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mOver-the-Credit-Limit None\u001b[0m\u001b[48;2;240;248;255m                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mReturn Payment Up to $40.\u001b[0m\u001b[48;2;240;248;255m                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mReturn Check None\u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNote: This account may not be eligible for balance transfers.\u001b[0m\u001b[48;2;240;248;255m                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mLoss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60 days late, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mand\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mapply the Penalty APR.\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow We Will Calculate Your Balance: We use the daily balance method (including new transactions).\u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPrime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.\u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255maWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.\u001b[0m\u001b[48;2;240;248;255m         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMaximum APR 29.99%.\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.\u001b[0m\u001b[48;2;240;248;255m                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mcWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.\u001b[0m\u001b[48;2;240;248;255m               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mon\u001b[0m\u001b[48;2;240;248;255m                                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthe amount of each purchase transaction or amount selected to create the plan, the number of billing \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mperiods\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255myou choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255myour My\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mChase Plan Fee will be disclosed during the activation of each My Chase Plan.\u001b[0m\u001b[48;2;240;248;255m                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed\u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mForces and their dependents relating to extensions of consumer credit. In general, the cost of consumer\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mcredit\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mto a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of 36\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mpercent. This rate must include, as applicable to the credit transaction or account: the costs \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255massociated with\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mcredit insurance premiums; fees for ancillary products sold in connection with the credit transaction; \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255many\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mapplication fee charged (other than certain application fees for specified credit transactions or \u001b[0m\u001b[48;2;240;248;255m     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255maccounts); and\u001b[0m\u001b[48;2;240;248;255m                                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255many participation fee charged (other than certain participation fees for a credit card account). To \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mreceive this\u001b[0m\u001b[48;2;240;248;255m                                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255minformation and a description of your payment obligation verbally, please call 1-800-235-9978.\u001b[0m\u001b[48;2;240;248;255m         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTERMS & CONDITIONS\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAuthorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255msubsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:\u001b[0m\u001b[48;2;240;248;255m               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m1. You authorize us to obtain credit bureau reports, employment, and income information about you that \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwe\u001b[0m\u001b[48;2;240;248;255m                                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwill use when considering your application for credit. We may obtain and use information about your\u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255maccounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit\u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbureaus and other entities. You also authorize us to obtain credit bureau reports and any other\u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255minformation about you in connection with: 1) extensions of credit on your account; 2) the \u001b[0m\u001b[48;2;240;248;255m             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255madministration,\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mreview or collection of your account; and 3) offering you enhanced or additional products and services.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIf\u001b[0m\u001b[48;2;240;248;255m                                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255myou ask, we will tell you the name and address of the credit bureau from which we obtained a report\u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabout you.\u001b[0m\u001b[48;2;240;248;255m                                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You agree to the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mterms of this agreement by: using the account or any card, authorizing their use, or making any payment\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mon the account.\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m3. By providing your mobile ph\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise.\u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mJson Output:\u001b[0m\u001b[48;2;240;248;255m                                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "│   │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven the following document, answer the following questions. If the answer doesn't exist in\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe document, enter 'None'.                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m2/25/23, 7:59 PM about:blank                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout:blank 1/4                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPRICING INFORMATION                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mINTEREST RATES AND INTEREST CHARGES                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPurchase Annual                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPercentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAfter that, 19.49%. This APR will vary with the market based on the Prime                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mRate.                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMy Chase Loan                                                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSM APR 19.49%. This APR will vary with the market based on the Prime Rate.                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPromotional offers with fixed APRs and varying durations may be available from              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtime to time on some accounts.                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mBalance Transfer APR 0% Intro APR for the first 18 months that your Account is open.        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAfter that, 19.49%. This APR will vary with the market based on the Prime                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mRate.                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mb                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPenalty APR and When                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mIt Applies                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mUp to 29.99%. This APR will vary with the market based on the Prime Rate.                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mc                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mWe may apply the Penalty APR to your account if you:                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mfail to make a Minimum Payment by the date and time that it is due; or                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmake a payment to us that is returned unpaid.                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow Long Will the Penalty APR Apply?: If we apply the Penalty APR for                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235meither of these reasons, the Penalty APR could potentially remain in effect                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mindefinitely.                                                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow to Avoid Paying                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mInterest on Purchases                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mYour due date will be a minimum of 21 days after the close of each billing cycle.           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mWe will not charge you interest on new purchases if you pay your entire balance             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mor Interest Saving Balance by the due date each month. We will begin charging               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235minterest on balance transfers and cash advances on the transaction date.                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMinimum Interest                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCharge                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNone                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCredit Card Tips from                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe Consumer Financial                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mProtection Bureau                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTo learn more about factors to consider when applying for or using a credit card,           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mvisit the website of the Consumer Financial Protection Bureau at                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhttp://www.consumerfinance.gov/learnmore.                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mFEES                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAnnual Membership                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mFee                                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNone                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMy Chase Plan                                                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSM Fee                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m(fixed finance charge)                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMonthly fee of 0% of the amount of each eligible purchase transaction or                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mamount selected to create a My Chase Plan while in the 0% Intro Purchase                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAPR period.                                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAfter that, monthly fee of 1.72% of the amount of each eligible purchase                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransaction or amount selected to create a My Chase Plan. The My Chase Plan                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mFee will be determined at the time each My Chase Plan is created and will                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mremain the same until the My Chase Plan is paid in full.                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235md                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTransaction Fees                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mBalance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mgreater,                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mon transfers made within 60 days of account opening. After that: Either $5 or 5%            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mof the amount of each transfer, whichever is greater.                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m2/25/23, 7:59 PM about:blank                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout:blank 2/4                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mForeign Transactions 3% of the amount of each transaction in U.S. dollars.                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPenalty Fees                                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mLate Payment Up to $40.                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mOver-the-Credit-Limit None                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mReturn Payment Up to $40.                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mReturn Check None                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNote: This account may not be eligible for balance transfers.                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mLoss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdays late, and                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mapply the Penalty APR.                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow We Will Calculate Your Balance: We use the daily balance method (including new          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransactions).                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPrime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235maWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAPR.                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMaximum APR 29.99%.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mis based on                                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe amount of each purchase transaction or amount selected to create the plan, the number of\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbilling periods                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myou choose to pay the balance in full, and other factors. The monthly and aggregate dollar  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mamount of your My                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mChase Plan Fee will be disclosed during the activation of each My Chase Plan.               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mArmed                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mForces and their dependents relating to extensions of consumer credit. In general, the cost \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mof consumer credit                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto a member of the Armed Forces and his or her dependent may not exceed an annual percentage\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mrate of 36                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mpercent. This rate must include, as applicable to the credit transaction or account: the    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcosts associated with                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcredit insurance premiums; fees for ancillary products sold in connection with the credit   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransaction; any                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mapplication fee charged (other than certain application fees for specified credit           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransactions or accounts); and                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many participation fee charged (other than certain participation fees for a credit card      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235maccount). To receive this                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235minformation and a description of your payment obligation verbally, please call              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1-800-235-9978.                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTERMS & CONDITIONS                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAuthorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A.,   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMember FDIC, a                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msubsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1. You authorize us to obtain credit bureau reports, employment, and income information     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout you that we                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwill use when considering your application for credit. We may obtain and use information    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout your                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235maccounts with us and others such as Checking, Deposit, Investment, and Utility accounts from\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcredit                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbureaus and other entities. You also authorize us to obtain credit bureau reports and any   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mother                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235minformation about you in connection with: 1) extensions of credit on your account; 2) the   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235madministration,                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mreview or collection of your account; and 3) offering you enhanced or additional products   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand services. If                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myou ask, we will tell you the name and address of the credit bureau from which we obtained a\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mreport                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout you.                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235magree to the                                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mterms of this agreement by: using the account or any card, authorizing their use, or making \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many payment                                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mon the account.                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m3. By providing your mobile ph                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise.                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "│   │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "│   │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
        "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"fees\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"annual membership fee\",\u001b[0m\u001b[48;2;245;245;220m                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"my chase plan fee\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mamount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, \u001b[0m\u001b[48;2;245;245;220m      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mmonthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mMy Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mwill remain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;245;245;220m                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"balance transfers intro fee\",\u001b[0m\u001b[48;2;245;245;220m                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Either $5 or 3% of the amount of each transfer, whichever is greater, on \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mtransfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each \u001b[0m\u001b[48;2;245;245;220m   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mtransfer, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 5\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"cash advances\",\u001b[0m\u001b[48;2;245;245;220m                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 10\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"foreign transactions\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",\u001b[0m\u001b[48;2;245;245;220m                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 3\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"late payment\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 40\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"over-the-credit-limit\",\u001b[0m\u001b[48;2;245;245;220m                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"return payment\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 40\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"return check\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"interest_rates\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"account_type\": \"purchase/my chase loan/balance transfer\",\u001b[0m\u001b[48;2;245;245;220m                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"rate\": 19.49\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"account_type\": \"cash advance\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"rate\": 29.49\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"account_type\": \"penalty\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"rate\": 29.99\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"fees\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"annual membership fee\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"my chase plan sm fee\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mselected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPlan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will \u001b[0m\u001b[48;2;245;245;220m     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mremain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;245;245;220m                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220meach transaction, whichever is greater. Foreign Transactions 3% of the amount of each transaction in \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mU.S. dollars.\",\u001b[0m\u001b[48;2;245;245;220m                                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 5\u001b[0m\u001b[48;2;245;245;220m                                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40. \u001b[0m\u001b[48;2;245;245;220m    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mReturn Check None\",\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 40\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"interest_rates\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"purchase/my chase loan/balance transfer\",\u001b[0m\u001b[48;2;245;245;220m                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 19.49\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"cash advance\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 29.49\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"penalty\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 26.99\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "│   │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
@@ -1237,27 +1110,33 @@
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                fail_results=[\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    FailResult(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        outcome='fail',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_message='Value must be exactly two words',\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='annual membership'\u001b[0m\u001b[48;2;240;255;240m                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='annual membership',\u001b[0m\u001b[48;2;240;255;240m                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_spans=None,\u001b[0m\u001b[48;2;240;255;240m                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        validated_chunk=None\u001b[0m\u001b[48;2;240;255;240m                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    )\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                ],\u001b[0m\u001b[48;2;240;255;240m                                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                additional_properties={},\u001b[0m\u001b[48;2;240;255;240m                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                path=['fees', 0, 'name']\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            ),\u001b[0m\u001b[48;2;240;255;240m                                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0\u001b[0m\u001b[48;2;240;255;240m                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': FieldReAsk(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                incorrect_value='my chase plan fee',\u001b[0m\u001b[48;2;240;255;240m                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                incorrect_value='my chase plan sm fee',\u001b[0m\u001b[48;2;240;255;240m                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                fail_results=[\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    FailResult(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        outcome='fail',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_message='Value must be exactly two words',\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='my chase'\u001b[0m\u001b[48;2;240;255;240m                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='my chase',\u001b[0m\u001b[48;2;240;255;240m                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_spans=None,\u001b[0m\u001b[48;2;240;255;240m                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        validated_chunk=None\u001b[0m\u001b[48;2;240;255;240m                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    )\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                ],\u001b[0m\u001b[48;2;240;255;240m                                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                additional_properties={},\u001b[0m\u001b[48;2;240;255;240m                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                path=['fees', 1, 'name']\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            ),\u001b[0m\u001b[48;2;240;255;240m                                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1265,57 +1144,23 @@
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mmonthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mMy Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mwill remain the same until the My Chase Plan is paid in full.',\u001b[0m\u001b[48;2;240;255;240m                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0\u001b[0m\u001b[48;2;240;255;240m                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'transaction fees', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': FieldReAsk(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                incorrect_value='balance transfers intro fee',\u001b[0m\u001b[48;2;240;255;240m                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                fail_results=[\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    FailResult(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        outcome='fail',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_message='Value must be exactly two words',\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='balance transfers'\u001b[0m\u001b[48;2;240;255;240m                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    )\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                ],\u001b[0m\u001b[48;2;240;255;240m                                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                path=['fees', 3, 'name']\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            ),\u001b[0m\u001b[48;2;240;255;240m                                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Either $5 or 3% of the amount of each transfer, whichever is greater, on \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each \u001b[0m\u001b[48;2;240;255;240m   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfer, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'transaction fees',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Balance Transfers Intro fee of either $5 or 3% of the amount of each \u001b[0m\u001b[48;2;240;255;240m      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$5 or 5% of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mamount of each transaction, whichever is greater. Foreign Transactions 3% of the amount of each \u001b[0m\u001b[48;2;240;255;240m       \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransaction in U.S. dollars.',\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 5.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'cash advances',\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 10.0\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'foreign transactions',\u001b[0m\u001b[48;2;240;255;240m                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': '3% of the amount of each transaction in U.S. dollars.',\u001b[0m\u001b[48;2;240;255;240m                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 3.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'penalty fees', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},\u001b[0m\u001b[48;2;240;255;240m                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': FieldReAsk(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                incorrect_value='over-the-credit-limit',\u001b[0m\u001b[48;2;240;255;240m                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                fail_results=[\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    FailResult(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        outcome='fail',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_message='Value must be exactly two words',\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='over the'\u001b[0m\u001b[48;2;240;255;240m                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    )\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                ],\u001b[0m\u001b[48;2;240;255;240m                                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                path=['fees', 8, 'name']\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            ),\u001b[0m\u001b[48;2;240;255;240m                                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0},\u001b[0m\u001b[48;2;240;255;240m                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'return check', 'explanation': 'None', 'value': 0.0}\u001b[0m\u001b[48;2;240;255;240m                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'penalty fees',\u001b[0m\u001b[48;2;240;255;240m                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to \u001b[0m\u001b[48;2;240;255;240m   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$40. Return Check None',\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 40.0\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        }\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ],\u001b[0m\u001b[48;2;240;255;240m                                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'interest_rates': [\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1323,7 +1168,7 @@
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'rate': 19.49\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'cash advance', 'rate': 29.49},\u001b[0m\u001b[48;2;240;255;240m                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'penalty', 'rate': 29.99}\u001b[0m\u001b[48;2;240;255;240m                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'penalty', 'rate': 26.99}\u001b[0m\u001b[48;2;240;255;240m                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "│   │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
@@ -1343,11 +1188,11 @@
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        ]\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      },\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0\u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"incorrect_value\": \"my chase plan fee\",\u001b[0m\u001b[48;2;240;248;255m                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"incorrect_value\": \"my chase plan sm fee\",\u001b[0m\u001b[48;2;240;248;255m                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"error_messages\": [\u001b[0m\u001b[48;2;240;248;255m                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m          \"Value must be exactly two words\"\u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        ]\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
@@ -1357,64 +1202,22 @@
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mof 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPlan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will \u001b[0m\u001b[48;2;240;248;255m     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mremain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;240;248;255m                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0\u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;240;248;255m                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"incorrect_value\": \"balance transfers intro fee\",\u001b[0m\u001b[48;2;240;248;255m                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"error_messages\": [\u001b[0m\u001b[48;2;240;248;255m                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m          \"Value must be exactly two words\"\u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        ]\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      },\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Either $5 or 3% of the amount of each transfer, whichever is greater, on \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mtransfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mtransfer, whichever is greater.\",\u001b[0m\u001b[48;2;240;248;255m                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mof the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255meach transaction, whichever is greater. Foreign Transactions 3% of the amount of each transaction in \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mU.S. dollars.\",\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 5.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"cash advances\",\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",\u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 10.0\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"foreign transactions\",\u001b[0m\u001b[48;2;240;248;255m                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",\u001b[0m\u001b[48;2;240;248;255m                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 3.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;240;248;255m                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"late payment\",\u001b[0m\u001b[48;2;240;248;255m                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;240;248;255m                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40. \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mReturn Check None\",\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 40.0\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"incorrect_value\": \"over-the-credit-limit\",\u001b[0m\u001b[48;2;240;248;255m                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"error_messages\": [\u001b[0m\u001b[48;2;240;248;255m                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m          \"Value must be exactly two words\"\u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        ]\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      },\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"return payment\",\u001b[0m\u001b[48;2;240;248;255m                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;240;248;255m                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 40.0\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"return check\",\u001b[0m\u001b[48;2;240;248;255m                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    }\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  ],\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \"interest_rates\": [\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
@@ -1428,7 +1231,7 @@
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"account_type\": \"penalty\",\u001b[0m\u001b[48;2;240;248;255m                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"rate\": 29.99\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"rate\": 26.99\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    }\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  ]\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
@@ -1439,100 +1242,85 @@
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mJson Output:\u001b[0m\u001b[48;2;240;248;255m                                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant only capable of communicating with valid JSON, and no other text.\u001b[0m\u001b[48;2;255;240;242m          \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;255;240;242m      \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;255;240;242m   \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242menter `null`.\u001b[0m\u001b[48;2;255;240;242m                                                                                          \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;255;240;242m                         \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;255;240;242m                    \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;255;240;242m   \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242metc.]}`\u001b[0m\u001b[48;2;255;240;242m                                                                                                \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;255;240;242m                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m                                                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"fees\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"annual membership fee\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"my chase plan fee\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"my chase plan sm fee\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mselected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPlan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will \u001b[0m\u001b[48;2;245;245;220m     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mremain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;245;245;220m                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"balance transfers intro fee\",\u001b[0m\u001b[48;2;245;245;220m                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Either $5 or 3% of the amount of each transfer, whichever is greater, on \u001b[0m\u001b[48;2;245;245;220m        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mtransfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each \u001b[0m\u001b[48;2;245;245;220m   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mtransfer, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the amount of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220meach transaction, whichever is greater. Foreign Transactions 3% of the amount of each transaction in \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mU.S. dollars.\",\u001b[0m\u001b[48;2;245;245;220m                                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 5.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"cash advances\",\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 10.0\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"foreign transactions\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",\u001b[0m\u001b[48;2;245;245;220m                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 3.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"late payment\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to $40. \u001b[0m\u001b[48;2;245;245;220m    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mReturn Check None\",\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 40.0\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"over-the-credit-limit\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"return payment\",\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 40.0\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"return check\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"interest_rates\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
@@ -1546,7 +1334,7 @@
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"penalty\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 29.99\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 26.99\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
@@ -1554,7 +1342,7 @@
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'fees': [\u001b[0m\u001b[48;2;240;255;240m                                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'annual membership', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'annual membership', 'explanation': 'None', 'value': 0},\u001b[0m\u001b[48;2;240;255;240m                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'my chase',\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1562,31 +1350,23 @@
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mmonthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mMy Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mwill remain the same until the My Chase Plan is paid in full.',\u001b[0m\u001b[48;2;240;255;240m                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0\u001b[0m\u001b[48;2;240;255;240m                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'transaction fees', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'balance transfers',\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Either $5 or 3% of the amount of each transfer, whichever is greater, on \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each \u001b[0m\u001b[48;2;240;255;240m   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfer, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'transaction fees',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Balance Transfers Intro fee of either $5 or 3% of the amount of each \u001b[0m\u001b[48;2;240;255;240m      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$5 or 5% of the amount of each transfer, whichever is greater. Cash Advances Either $10 or 5% of the \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mamount of each transaction, whichever is greater. Foreign Transactions 3% of the amount of each \u001b[0m\u001b[48;2;240;255;240m       \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransaction in U.S. dollars.',\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 5.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'cash advances',\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 10.0\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'foreign transactions',\u001b[0m\u001b[48;2;240;255;240m                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': '3% of the amount of each transaction in U.S. dollars.',\u001b[0m\u001b[48;2;240;255;240m                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 3.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'penalty fees', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},\u001b[0m\u001b[48;2;240;255;240m                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'over the', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0},\u001b[0m\u001b[48;2;240;255;240m                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'return check', 'explanation': 'None', 'value': 0.0}\u001b[0m\u001b[48;2;240;255;240m                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'penalty fees',\u001b[0m\u001b[48;2;240;255;240m                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Late Payment Up to $40. Over-the-Credit-Limit None Return Payment Up to \u001b[0m\u001b[48;2;240;255;240m   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$40. Return Check None',\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 40.0\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        }\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ],\u001b[0m\u001b[48;2;240;255;240m                                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'interest_rates': [\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1594,14 +1374,14 @@
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'rate': 19.49\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'cash advance', 'rate': 29.49},\u001b[0m\u001b[48;2;240;255;240m                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'penalty', 'rate': 29.99}\u001b[0m\u001b[48;2;240;255;240m                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'penalty', 'rate': 26.99}\u001b[0m\u001b[48;2;240;255;240m                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n"
       ]
      },
-     "execution_count": 136,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1627,7 +1407,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.12.1"
   },
   "vscode": {
    "interpreter": {
diff --git a/docs/examples/generate_structured_data.ipynb b/docs/examples/generate_structured_data.ipynb
index ee80c9d24..2a4d5a163 100644
--- a/docs/examples/generate_structured_data.ipynb
+++ b/docs/examples/generate_structured_data.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [
     {
@@ -61,9 +61,18 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 2,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n",
+      "  from tqdm.autonotebook import tqdm, trange\n"
+     ]
+    }
+   ],
    "source": [
     "from pydantic import BaseModel, Field\n",
     "from guardrails.hub import ValidLength, TwoWords, ValidRange\n",
@@ -73,7 +82,7 @@
     "prompt = \"\"\"\n",
     "Generate a dataset of fake user orders. Each row of the dataset should be valid.\n",
     "\n",
-    "${gr.complete_json_suffix}\n",
+    "${gr.complete_xml_suffix}\n",
     "\"\"\"\n",
     "\n",
     "class Order(BaseModel):\n",
@@ -109,7 +118,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 3,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -120,11 +129,36 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "guard = gd.Guard.from_pydantic(output_class=Orders)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Step 3: Wrap the LLM API call with `Guard`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
    "metadata": {},
    "outputs": [],
    "source": [
-    "guard = gd.Guard.from_pydantic(output_class=Orders, prompt=prompt)"
+    "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n",
+    "# import os\n",
+    "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n",
+    "\n",
+    "res = guard(\n",
+    "    model=\"gpt-4o\",\n",
+    "    messages=[{\"role\":\"user\", \"content\": prompt}],\n",
+    "    max_tokens=2048,\n",
+    "    temperature=0\n",
+    ")\n"
    ]
   },
   {
@@ -136,7 +170,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [
     {
@@ -149,19 +183,18 @@
        "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
        "\n",
        "<output>\n",
-       "    <list name=\"user_orders\" description=\"Generate a list of user, and how many orders they have placed in the \n",
-       "past.\" format=\"guardrails/valid_length: min=10 max=10\">\n",
-       "        <object>\n",
-       "            <string name=\"user_id\" description=\"The user's id.\"/>\n",
-       "            <string name=\"user_name\" description=\"The user's first name and last name\" \n",
-       "format=\"guardrails/two_words\"/>\n",
-       "            <integer name=\"num_orders\" description=\"The number of orders the user has placed\" \n",
-       "format=\"guardrails/valid_range: min=0 max=50\"/>\n",
-       "        </object>\n",
-       "    </list>\n",
+       "  <list description=\"Generate a list of user, and how many orders they have placed in the past.\" \n",
+       "format=\"guardrails/valid_length: 10 10\" name=\"user_orders\" required=\"true\">\n",
+       "    <object format=\"guardrails/valid_length: 10 10\" required=\"true\">\n",
+       "      <string description=\"The user's id.\" name=\"user_id\" required=\"true\"></string>\n",
+       "      <string description=\"The user's first name and last name\" format=\"guardrails/two_words\" name=\"user_name\" \n",
+       "required=\"true\"></string>\n",
+       "      <integer description=\"The number of orders the user has placed\" format=\"guardrails/valid_range: 0 50\" \n",
+       "name=\"num_orders\" required=\"true\"></integer>\n",
+       "    </object>\n",
+       "  </list>\n",
        "</output>\n",
        "\n",
-       "\n",
        "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n",
        "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n",
        "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n",
@@ -184,19 +217,18 @@
        "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
        "\n",
        "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n",
-       "\u001b[39m    \u001b[0m\n",
-       "\u001b[39m        \u001b[0m\n",
-       "\u001b[39m            \u001b[0m\n",
-       "\u001b[39m            \u001b[0m\n",
-       "\u001b[39m            \u001b[0m\n",
-       "\u001b[39m        <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n",
-       "\u001b[39m    <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n",
+       "\u001b[39m  \u001b[0m\n",
+       "\u001b[39m    \u001b[0m\n",
+       "\u001b[39m      <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n",
+       "\u001b[39m      <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n",
+       "\u001b[39m      <\u001b[0m\u001b[35m/\u001b[0m\u001b[95minteger\u001b[0m\u001b[39m>\u001b[0m\n",
+       "\u001b[39m    <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n",
+       "\u001b[39m  <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n",
        "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n",
        "\n",
-       "\n",
        "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n",
        "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n",
        "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n",
@@ -216,51 +248,162 @@
     }
    ],
    "source": [
-    "print(guard.rail.prompt)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Step 3: Wrap the LLM API call with `Guard`"
+    "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
```json\n",
+       "{\n",
+       "  \"user_orders\": [\n",
+       "    {\n",
+       "      \"user_id\": \"u001\",\n",
+       "      \"user_name\": \"John Doe\",\n",
+       "      \"num_orders\": 15\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u002\",\n",
+       "      \"user_name\": \"Jane Smith\",\n",
+       "      \"num_orders\": 22\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u003\",\n",
+       "      \"user_name\": \"Alice Johnson\",\n",
+       "      \"num_orders\": 8\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u004\",\n",
+       "      \"user_name\": \"Bob Brown\",\n",
+       "      \"num_orders\": 30\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u005\",\n",
+       "      \"user_name\": \"Charlie Davis\",\n",
+       "      \"num_orders\": 12\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u006\",\n",
+       "      \"user_name\": \"Diana Evans\",\n",
+       "      \"num_orders\": 25\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u007\",\n",
+       "      \"user_name\": \"Eve Foster\",\n",
+       "      \"num_orders\": 18\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u008\",\n",
+       "      \"user_name\": \"Frank Green\",\n",
+       "      \"num_orders\": 10\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u009\",\n",
+       "      \"user_name\": \"Grace Hill\",\n",
+       "      \"num_orders\": 5\n",
+       "    },\n",
+       "    {\n",
+       "      \"user_id\": \"u010\",\n",
+       "      \"user_name\": \"Henry King\",\n",
+       "      \"num_orders\": 20\n",
+       "    }\n",
+       "  ]\n",
+       "}\n",
+       "```\n",
+       "
\n" + ], + "text/plain": [ + "```json\n", + "\u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_orders\"\u001b[0m: \u001b[1m[\u001b[0m\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u001\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"John Doe\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m15\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u002\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Jane Smith\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m22\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u003\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Alice Johnson\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m8\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u004\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Bob Brown\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m30\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u005\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Charlie Davis\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m12\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u006\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Diana Evans\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m25\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u007\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Eve Foster\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m18\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u008\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Frank Green\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m10\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u009\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Grace Hill\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m5\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m\"user_id\"\u001b[0m: \u001b[32m\"u010\"\u001b[0m,\n", + " \u001b[32m\"user_name\"\u001b[0m: \u001b[32m\"Henry King\"\u001b[0m,\n", + " \u001b[32m\"num_orders\"\u001b[0m: \u001b[1;36m20\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", + " \u001b[1m]\u001b[0m\n", + "\u001b[1m}\u001b[0m\n", + "```\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, { "data": { "text/plain": [ - "{'user_orders': [{'user_id': 'u123', 'user_name': 'John Doe', 'num_orders': 5},\n", - " {'user_id': 'u456', 'user_name': 'Jane Smith', 'num_orders': 12},\n", - " {'user_id': 'u789', 'user_name': 'Alice Johnson', 'num_orders': 3},\n", - " {'user_id': 'u234', 'user_name': 'Michael Brown', 'num_orders': 8},\n", - " {'user_id': 'u567', 'user_name': 'Emily Davis', 'num_orders': 20},\n", - " {'user_id': 'u890', 'user_name': 'David Wilson', 'num_orders': 15},\n", - " {'user_id': 'u345', 'user_name': 'Sarah Martinez', 'num_orders': 7},\n", - " {'user_id': 'u678', 'user_name': 'Robert Anderson', 'num_orders': 10},\n", - " {'user_id': 'u901', 'user_name': 'Laura Thompson', 'num_orders': 2},\n", - " {'user_id': 'u432', 'user_name': 'William Garcia', 'num_orders': 18}]}" + "{'user_orders': [{'user_id': 'u001',\n", + " 'user_name': 'John Doe',\n", + " 'num_orders': 15},\n", + " {'user_id': 'u002', 'user_name': 'Jane Smith', 'num_orders': 22},\n", + " {'user_id': 'u003', 'user_name': 'Alice Johnson', 'num_orders': 8},\n", + " {'user_id': 'u004', 'user_name': 'Bob Brown', 'num_orders': 30},\n", + " {'user_id': 'u005', 'user_name': 'Charlie Davis', 'num_orders': 12},\n", + " {'user_id': 'u006', 'user_name': 'Diana Evans', 'num_orders': 25},\n", + " {'user_id': 'u007', 'user_name': 'Eve Foster', 'num_orders': 18},\n", + " {'user_id': 'u008', 'user_name': 'Frank Green', 'num_orders': 10},\n", + " {'user_id': 'u009', 'user_name': 'Grace Hill', 'num_orders': 5},\n", + " {'user_id': 'u010', 'user_name': 'Henry King', 'num_orders': 20}]}" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "import openai\n", - "\n", - "\n", - "res = guard(\n", - " openai.chat.completions.create,\n", - " max_tokens=2048,\n", - " temperature=0\n", - ")\n", - "res.validated_output\n" + "print(res.raw_llm_output)\n", + "res.validated_output" ] }, { @@ -275,7 +418,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -284,74 +427,120 @@ "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Generate a dataset of fake user orders. Each row of the dataset should be valid.                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <list name=\"user_orders\" description=\"Generate a list of user, and how many orders they have placed │ │\n",
-       "    │ │ in the past.\" format=\"guardrails/valid_length: min=10 max=10\">                                          │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <string name=\"user_id\" description=\"The user's id.\"/>                                       │ │\n",
-       "    │ │             <string name=\"user_name\" description=\"The user's first name and last name\"                  │ │\n",
-       "    │ │ format=\"guardrails/two_words\"/>                                                                         │ │\n",
-       "    │ │             <integer name=\"num_orders\" description=\"The number of orders the user has placed\"           │ │\n",
-       "    │ │ format=\"guardrails/valid_range: min=0 max=50\"/>                                                         │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ Generate a dataset of fake user orders. Each row of the dataset should be valid.             │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <list description=\"Generate a list of user, and how many orders they have placed in the    │ │ │\n",
+       "    │ │ │      │ past.\" format=\"guardrails/valid_length: 10 10\" name=\"user_orders\" required=\"true\">           │ │ │\n",
+       "    │ │ │      │     <object format=\"guardrails/valid_length: 10 10\" required=\"true\">                         │ │ │\n",
+       "    │ │ │      │       <string description=\"The user's id.\" name=\"user_id\" required=\"true\"></string>          │ │ │\n",
+       "    │ │ │      │       <string description=\"The user's first name and last name\"                              │ │ │\n",
+       "    │ │ │      │ format=\"guardrails/two_words\" name=\"user_name\" required=\"true\"></string>                     │ │ │\n",
+       "    │ │ │      │       <integer description=\"The number of orders the user has placed\"                        │ │ │\n",
+       "    │ │ │      │ format=\"guardrails/valid_range: 0 50\" name=\"num_orders\" required=\"true\"></integer>           │ │ │\n",
+       "    │ │ │      │     </object>                                                                                │ │ │\n",
+       "    │ │ │      │   </list>                                                                                    │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ {\"user_orders\":[{\"user_id\":\"u123\",\"user_name\":\"John                                                     │ │\n",
-       "    │ │ Doe\",\"num_orders\":5},{\"user_id\":\"u456\",\"user_name\":\"Jane                                                │ │\n",
-       "    │ │ Smith\",\"num_orders\":12},{\"user_id\":\"u789\",\"user_name\":\"Alice                                            │ │\n",
-       "    │ │ Johnson\",\"num_orders\":3},{\"user_id\":\"u234\",\"user_name\":\"Michael                                         │ │\n",
-       "    │ │ Brown\",\"num_orders\":8},{\"user_id\":\"u567\",\"user_name\":\"Emily                                             │ │\n",
-       "    │ │ Davis\",\"num_orders\":20},{\"user_id\":\"u890\",\"user_name\":\"David                                            │ │\n",
-       "    │ │ Wilson\",\"num_orders\":15},{\"user_id\":\"u345\",\"user_name\":\"Sarah                                           │ │\n",
-       "    │ │ Martinez\",\"num_orders\":7},{\"user_id\":\"u678\",\"user_name\":\"Robert                                         │ │\n",
-       "    │ │ Anderson\",\"num_orders\":10},{\"user_id\":\"u901\",\"user_name\":\"Laura                                         │ │\n",
-       "    │ │ Thompson\",\"num_orders\":2},{\"user_id\":\"u432\",\"user_name\":\"William Garcia\",\"num_orders\":18}]}             │ │\n",
+       "    │ │ ```json                                                                                                 │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"user_orders\": [                                                                                      │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u001\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"John Doe\",                                                                          │ │\n",
+       "    │ │       \"num_orders\": 15                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u002\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Jane Smith\",                                                                        │ │\n",
+       "    │ │       \"num_orders\": 22                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u003\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Alice Johnson\",                                                                     │ │\n",
+       "    │ │       \"num_orders\": 8                                                                                   │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u004\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Bob Brown\",                                                                         │ │\n",
+       "    │ │       \"num_orders\": 30                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u005\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Charlie Davis\",                                                                     │ │\n",
+       "    │ │       \"num_orders\": 12                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u006\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Diana Evans\",                                                                       │ │\n",
+       "    │ │       \"num_orders\": 25                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u007\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Eve Foster\",                                                                        │ │\n",
+       "    │ │       \"num_orders\": 18                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u008\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Frank Green\",                                                                       │ │\n",
+       "    │ │       \"num_orders\": 10                                                                                  │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u009\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Grace Hill\",                                                                        │ │\n",
+       "    │ │       \"num_orders\": 5                                                                                   │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"user_id\": \"u010\",                                                                                │ │\n",
+       "    │ │       \"user_name\": \"Henry King\",                                                                        │ │\n",
+       "    │ │       \"num_orders\": 20                                                                                  │ │\n",
+       "    │ │     }                                                                                                   │ │\n",
+       "    │ │   ]                                                                                                     │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
+       "    │ │ ```                                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     'user_orders': [                                                                                    │ │\n",
-       "    │ │         {'user_id': 'u123', 'user_name': 'John Doe', 'num_orders': 5},                                  │ │\n",
-       "    │ │         {'user_id': 'u456', 'user_name': 'Jane Smith', 'num_orders': 12},                               │ │\n",
-       "    │ │         {'user_id': 'u789', 'user_name': 'Alice Johnson', 'num_orders': 3},                             │ │\n",
-       "    │ │         {'user_id': 'u234', 'user_name': 'Michael Brown', 'num_orders': 8},                             │ │\n",
-       "    │ │         {'user_id': 'u567', 'user_name': 'Emily Davis', 'num_orders': 20},                              │ │\n",
-       "    │ │         {'user_id': 'u890', 'user_name': 'David Wilson', 'num_orders': 15},                             │ │\n",
-       "    │ │         {'user_id': 'u345', 'user_name': 'Sarah Martinez', 'num_orders': 7},                            │ │\n",
-       "    │ │         {'user_id': 'u678', 'user_name': 'Robert Anderson', 'num_orders': 10},                          │ │\n",
-       "    │ │         {'user_id': 'u901', 'user_name': 'Laura Thompson', 'num_orders': 2},                            │ │\n",
-       "    │ │         {'user_id': 'u432', 'user_name': 'William Garcia', 'num_orders': 18}                            │ │\n",
+       "    │ │         {'user_id': 'u001', 'user_name': 'John Doe', 'num_orders': 15},                                 │ │\n",
+       "    │ │         {'user_id': 'u002', 'user_name': 'Jane Smith', 'num_orders': 22},                               │ │\n",
+       "    │ │         {'user_id': 'u003', 'user_name': 'Alice Johnson', 'num_orders': 8},                             │ │\n",
+       "    │ │         {'user_id': 'u004', 'user_name': 'Bob Brown', 'num_orders': 30},                                │ │\n",
+       "    │ │         {'user_id': 'u005', 'user_name': 'Charlie Davis', 'num_orders': 12},                            │ │\n",
+       "    │ │         {'user_id': 'u006', 'user_name': 'Diana Evans', 'num_orders': 25},                              │ │\n",
+       "    │ │         {'user_id': 'u007', 'user_name': 'Eve Foster', 'num_orders': 18},                               │ │\n",
+       "    │ │         {'user_id': 'u008', 'user_name': 'Frank Green', 'num_orders': 10},                              │ │\n",
+       "    │ │         {'user_id': 'u009', 'user_name': 'Grace Hill', 'num_orders': 5},                                │ │\n",
+       "    │ │         {'user_id': 'u010', 'user_name': 'Henry King', 'num_orders': 20}                                │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
@@ -362,74 +551,120 @@
        "Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGenerate a dataset of fake user orders. Each row of the dataset should be valid.\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGenerate a dataset of fake user orders. Each row of the dataset should be valid.            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`.                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\"user_orders\":[{\"user_id\":\"u123\",\"user_name\":\"John \u001b[0m\u001b[48;2;245;245;220m                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mDoe\",\"num_orders\":5},{\"user_id\":\"u456\",\"user_name\":\"Jane \u001b[0m\u001b[48;2;245;245;220m                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mSmith\",\"num_orders\":12},{\"user_id\":\"u789\",\"user_name\":\"Alice \u001b[0m\u001b[48;2;245;245;220m                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJohnson\",\"num_orders\":3},{\"user_id\":\"u234\",\"user_name\":\"Michael \u001b[0m\u001b[48;2;245;245;220m                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mBrown\",\"num_orders\":8},{\"user_id\":\"u567\",\"user_name\":\"Emily \u001b[0m\u001b[48;2;245;245;220m                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mDavis\",\"num_orders\":20},{\"user_id\":\"u890\",\"user_name\":\"David \u001b[0m\u001b[48;2;245;245;220m                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mWilson\",\"num_orders\":15},{\"user_id\":\"u345\",\"user_name\":\"Sarah \u001b[0m\u001b[48;2;245;245;220m                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mMartinez\",\"num_orders\":7},{\"user_id\":\"u678\",\"user_name\":\"Robert \u001b[0m\u001b[48;2;245;245;220m                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mAnderson\",\"num_orders\":10},{\"user_id\":\"u901\",\"user_name\":\"Laura \u001b[0m\u001b[48;2;245;245;220m                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mThompson\",\"num_orders\":2},{\"user_id\":\"u432\",\"user_name\":\"William Garcia\",\"num_orders\":18}]}\u001b[0m\u001b[48;2;245;245;220m            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"user_orders\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u001\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"John Doe\",\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 15\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u002\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Jane Smith\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 22\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u003\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Alice Johnson\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 8\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u004\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Bob Brown\",\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 30\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u005\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Charlie Davis\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 12\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u006\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Diana Evans\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 25\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u007\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Eve Foster\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 18\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u008\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Frank Green\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 10\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u009\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Grace Hill\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 5\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_id\": \"u010\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"user_name\": \"Henry King\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"num_orders\": 20\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'user_orders': [\u001b[0m\u001b[48;2;240;255;240m                                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u123', 'user_name': 'John Doe', 'num_orders': 5},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u456', 'user_name': 'Jane Smith', 'num_orders': 12},\u001b[0m\u001b[48;2;240;255;240m                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u789', 'user_name': 'Alice Johnson', 'num_orders': 3},\u001b[0m\u001b[48;2;240;255;240m                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u234', 'user_name': 'Michael Brown', 'num_orders': 8},\u001b[0m\u001b[48;2;240;255;240m                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u567', 'user_name': 'Emily Davis', 'num_orders': 20},\u001b[0m\u001b[48;2;240;255;240m                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u890', 'user_name': 'David Wilson', 'num_orders': 15},\u001b[0m\u001b[48;2;240;255;240m                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u345', 'user_name': 'Sarah Martinez', 'num_orders': 7},\u001b[0m\u001b[48;2;240;255;240m                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u678', 'user_name': 'Robert Anderson', 'num_orders': 10},\u001b[0m\u001b[48;2;240;255;240m                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u901', 'user_name': 'Laura Thompson', 'num_orders': 2},\u001b[0m\u001b[48;2;240;255;240m                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u432', 'user_name': 'William Garcia', 'num_orders': 18}\u001b[0m\u001b[48;2;240;255;240m                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u001', 'user_name': 'John Doe', 'num_orders': 15},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u002', 'user_name': 'Jane Smith', 'num_orders': 22},\u001b[0m\u001b[48;2;240;255;240m                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u003', 'user_name': 'Alice Johnson', 'num_orders': 8},\u001b[0m\u001b[48;2;240;255;240m                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u004', 'user_name': 'Bob Brown', 'num_orders': 30},\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u005', 'user_name': 'Charlie Davis', 'num_orders': 12},\u001b[0m\u001b[48;2;240;255;240m                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u006', 'user_name': 'Diana Evans', 'num_orders': 25},\u001b[0m\u001b[48;2;240;255;240m                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u007', 'user_name': 'Eve Foster', 'num_orders': 18},\u001b[0m\u001b[48;2;240;255;240m                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u008', 'user_name': 'Frank Green', 'num_orders': 10},\u001b[0m\u001b[48;2;240;255;240m                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u009', 'user_name': 'Grace Hill', 'num_orders': 5},\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 'u010', 'user_name': 'Henry King', 'num_orders': 20}\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
@@ -461,7 +696,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.12.1"
   },
   "orig_nbformat": 4
  },
diff --git a/docs/examples/generate_structured_data_cohere.ipynb b/docs/examples/generate_structured_data_cohere.ipynb
index e22624ea8..e110693a9 100644
--- a/docs/examples/generate_structured_data_cohere.ipynb
+++ b/docs/examples/generate_structured_data_cohere.ipynb
@@ -41,7 +41,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 12,
    "id": "6a7c7d4a",
    "metadata": {},
    "outputs": [
@@ -60,7 +60,10 @@
       "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mvalid_range...\u001b[0m\n",
       "✅Successfully installed guardrails/valid_range!\n",
       "\n",
-      "\n"
+      "\n",
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.1\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
      ]
     }
    ],
@@ -68,7 +71,7 @@
     "!guardrails hub install hub://guardrails/valid_length --quiet\n",
     "!guardrails hub install hub://guardrails/two_words --quiet\n",
     "!guardrails hub install hub://guardrails/valid_range --quiet\n",
-    "!pip install cohere==5.3.2 --quiet"
+    "!pip install cohere --quiet"
    ]
   },
   {
@@ -76,12 +79,15 @@
    "id": "72d3938a",
    "metadata": {},
    "source": [
-    "Defined what our data should look like in pydantic"
+    "Defined what our data should look like in pydantic\n",
+    "\n",
+    "Note: 1-indexed is an example of passing non-validator instructions on a per field level via the `format` field.\n",
+    "It will throw a validator warning and is to be expected."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 25,
    "id": "3088fd99",
    "metadata": {},
    "outputs": [],
@@ -121,17 +127,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 22,
    "id": "840006ca-21ca-4f76-9ce1-e406d5d68412",
    "metadata": {},
    "outputs": [],
    "source": [
-    "import cohere\n",
-    "import os\n",
-    "\n",
-    "api_key = os.environ['COHERE_API_KEY']\n",
-    "\n",
-    "co = cohere.Client(api_key=api_key)"
+    "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n",
+    "# import os\n",
+    "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\""
    ]
   },
   {
@@ -144,28 +147,18 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 27,
    "id": "42766922-14d0-4b5e-853a-23f05b896a09",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/guardrails/validatorsattr.py:307: UserWarning: Validator 1-indexed is not installed!\n",
-      "  warnings.warn(f\"Validator {validator_name} is not installed!\")\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
+    "from rich import print\n",
     "import guardrails as gd\n",
-    "guard = gd.Guard.from_pydantic(output_class=Orders, prompt=prompt)\n",
-    "\n",
-    "res = co.chat(message=\"hi\")\n",
+    "guard = gd.Guard.from_pydantic(output_class=Orders)\n",
     "\n",
     "raw_llm_response, validated_response, *rest = guard(\n",
-    "\tco.chat,\n",
-    "\tmodel=\"command\",\n",
+    " \tmessages=[{\"role\":\"user\", \"content\":prompt}],\n",
+    "\tmodel=\"command-r\",\n",
     "\tmax_tokens=1024,\n",
     "\ttemperature=0.3\n",
     ")"
@@ -181,7 +174,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 28,
    "id": "0e910d87",
    "metadata": {},
    "outputs": [
@@ -199,19 +192,18 @@
        "    │ │ it into.                                                                                                │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <list name=\"user_orders\" description=\"Generate a list of users and how many orders they have placed │ │\n",
-       "    │ │ in the past.\" format=\"guardrails/valid_length: min=10 max=10\">                                          │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <integer name=\"user_id\" description=\"The user's id.\" format=\"1-indexed\"/>                   │ │\n",
-       "    │ │             <string name=\"user_name\" description=\"The user's first name and last name\"                  │ │\n",
-       "    │ │ format=\"guardrails/two_words\"/>                                                                         │ │\n",
-       "    │ │             <integer name=\"num_orders\" description=\"The number of orders the user has placed\"           │ │\n",
-       "    │ │ format=\"guardrails/valid_range: min=0 max=50\"/>                                                         │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
+       "    │ │   <list description=\"Generate a list of users and how many orders they have placed in the past.\"        │ │\n",
+       "    │ │ format=\"guardrails/valid_length: 10 10\" name=\"user_orders\" required=\"true\">                             │ │\n",
+       "    │ │     <object format=\"guardrails/valid_length: 10 10\" required=\"true\">                                    │ │\n",
+       "    │ │       <integer description=\"The user's id.\" name=\"user_id\" required=\"true\"></integer>                   │ │\n",
+       "    │ │       <string description=\"The user's first name and last name\" format=\"guardrails/two_words\"           │ │\n",
+       "    │ │ name=\"user_name\" required=\"true\"></string>                                                              │ │\n",
+       "    │ │       <integer description=\"The number of orders the user has placed\" format=\"guardrails/valid_range: 0 │ │\n",
+       "    │ │ 50\" name=\"num_orders\" required=\"true\"></integer>                                                        │ │\n",
+       "    │ │     </object>                                                                                           │ │\n",
+       "    │ │   </list>                                                                                               │ │\n",
        "    │ │ </output>                                                                                               │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
        "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
        "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
        "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
@@ -245,54 +237,54 @@
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     \"user_orders\": [                                                                                    │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 1,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"John Mcdonald\",                                                               │ │\n",
-       "    │ │             \"num_orders\": 6                                                                             │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 2,                                                                               │ │\n",
+       "    │ │             \"user_id\": 3,                                                                               │ │\n",
        "    │ │             \"user_name\": \"Jane Smith\",                                                                  │ │\n",
-       "    │ │             \"num_orders\": 4                                                                             │ │\n",
+       "    │ │             \"num_orders\": 12                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 3,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"David Lee\",                                                                   │ │\n",
-       "    │ │             \"num_orders\": 2                                                                             │ │\n",
+       "    │ │             \"user_id\": 1,                                                                               │ │\n",
+       "    │ │             \"user_name\": \"Michael Jones\",                                                               │ │\n",
+       "    │ │             \"num_orders\": 18                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 4,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Rachelle Gonzalez\",                                                           │ │\n",
-       "    │ │             \"num_orders\": 1                                                                             │ │\n",
+       "    │ │             \"user_name\": \"Mary Brown\",                                                                  │ │\n",
+       "    │ │             \"num_orders\": 9                                                                             │ │\n",
+       "    │ │         },                                                                                              │ │\n",
+       "    │ │         {                                                                                               │ │\n",
+       "    │ │             \"user_id\": 2,                                                                               │ │\n",
+       "    │ │             \"user_name\": \"David Miller\",                                                                │ │\n",
+       "    │ │             \"num_orders\": 21                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 5,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Frank Anderson\",                                                              │ │\n",
-       "    │ │             \"num_orders\": 3                                                                             │ │\n",
+       "    │ │             \"user_name\": \"Linda Martin\",                                                                │ │\n",
+       "    │ │             \"num_orders\": 15                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 6,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Lisa Taylor\",                                                                 │ │\n",
-       "    │ │             \"num_orders\": 5                                                                             │ │\n",
+       "    │ │             \"user_name\": \"Robert Wilson\",                                                               │ │\n",
+       "    │ │             \"num_orders\": 7                                                                             │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 7,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Peter Wilson\",                                                                │ │\n",
-       "    │ │             \"num_orders\": 7                                                                             │ │\n",
+       "    │ │             \"user_name\": \"Jennifer Taylor\",                                                             │ │\n",
+       "    │ │             \"num_orders\": 10                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 8,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Micheal Harris\",                                                              │ │\n",
+       "    │ │             \"user_name\": \"Kevin Anderson\",                                                              │ │\n",
        "    │ │             \"num_orders\": 4                                                                             │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 9,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Sarah Anderson\",                                                              │ │\n",
-       "    │ │             \"num_orders\": 2                                                                             │ │\n",
+       "    │ │             \"user_name\": \"Sarah Thompson\",                                                              │ │\n",
+       "    │ │             \"num_orders\": 23                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             \"user_id\": 10,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Jessica Taylor\",                                                              │ │\n",
-       "    │ │             \"num_orders\": 1                                                                             │ │\n",
+       "    │ │             \"user_name\": \"Frank Davis\",                                                                 │ │\n",
+       "    │ │             \"num_orders\": 11                                                                            │ │\n",
        "    │ │         }                                                                                               │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
@@ -300,16 +292,16 @@
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     'user_orders': [                                                                                    │ │\n",
-       "    │ │         {'user_id': 1, 'user_name': 'John Mcdonald', 'num_orders': 6},                                  │ │\n",
-       "    │ │         {'user_id': 2, 'user_name': 'Jane Smith', 'num_orders': 4},                                     │ │\n",
-       "    │ │         {'user_id': 3, 'user_name': 'David Lee', 'num_orders': 2},                                      │ │\n",
-       "    │ │         {'user_id': 4, 'user_name': 'Rachelle Gonzalez', 'num_orders': 1},                              │ │\n",
-       "    │ │         {'user_id': 5, 'user_name': 'Frank Anderson', 'num_orders': 3},                                 │ │\n",
-       "    │ │         {'user_id': 6, 'user_name': 'Lisa Taylor', 'num_orders': 5},                                    │ │\n",
-       "    │ │         {'user_id': 7, 'user_name': 'Peter Wilson', 'num_orders': 7},                                   │ │\n",
-       "    │ │         {'user_id': 8, 'user_name': 'Micheal Harris', 'num_orders': 4},                                 │ │\n",
-       "    │ │         {'user_id': 9, 'user_name': 'Sarah Anderson', 'num_orders': 2},                                 │ │\n",
-       "    │ │         {'user_id': 10, 'user_name': 'Jessica Taylor', 'num_orders': 1}                                 │ │\n",
+       "    │ │         {'user_id': 3, 'user_name': 'Jane Smith', 'num_orders': 12},                                    │ │\n",
+       "    │ │         {'user_id': 1, 'user_name': 'Michael Jones', 'num_orders': 18},                                 │ │\n",
+       "    │ │         {'user_id': 4, 'user_name': 'Mary Brown', 'num_orders': 9},                                     │ │\n",
+       "    │ │         {'user_id': 2, 'user_name': 'David Miller', 'num_orders': 21},                                  │ │\n",
+       "    │ │         {'user_id': 5, 'user_name': 'Linda Martin', 'num_orders': 15},                                  │ │\n",
+       "    │ │         {'user_id': 6, 'user_name': 'Robert Wilson', 'num_orders': 7},                                  │ │\n",
+       "    │ │         {'user_id': 7, 'user_name': 'Jennifer Taylor', 'num_orders': 10},                               │ │\n",
+       "    │ │         {'user_id': 8, 'user_name': 'Kevin Anderson', 'num_orders': 4},                                 │ │\n",
+       "    │ │         {'user_id': 9, 'user_name': 'Sarah Thompson', 'num_orders': 23},                                │ │\n",
+       "    │ │         {'user_id': 10, 'user_name': 'Frank Davis', 'num_orders': 11}                                   │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
@@ -328,19 +320,18 @@
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
@@ -374,54 +365,54 @@
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"user_orders\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 1,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"John Mcdonald\",\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 6\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 2,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 3,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Jane Smith\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 4\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 12\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 3,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"David Lee\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 2\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 1,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Michael Jones\",\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 18\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 4,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Rachelle Gonzalez\",\u001b[0m\u001b[48;2;245;245;220m                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 1\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Mary Brown\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 9\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 2,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"David Miller\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 21\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 5,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Frank Anderson\",\u001b[0m\u001b[48;2;245;245;220m                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 3\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Linda Martin\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 15\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 6,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Lisa Taylor\",\u001b[0m\u001b[48;2;245;245;220m                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 5\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Robert Wilson\",\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 7\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 7,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Peter Wilson\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 7\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Jennifer Taylor\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 10\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 8,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Micheal Harris\",\u001b[0m\u001b[48;2;245;245;220m                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Kevin Anderson\",\u001b[0m\u001b[48;2;245;245;220m                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 4\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 9,\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Sarah Anderson\",\u001b[0m\u001b[48;2;245;245;220m                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 2\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Sarah Thompson\",\u001b[0m\u001b[48;2;245;245;220m                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 23\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_id\": 10,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Jessica Taylor\",\u001b[0m\u001b[48;2;245;245;220m                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 1\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"user_name\": \"Frank Davis\",\u001b[0m\u001b[48;2;245;245;220m                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"num_orders\": 11\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
@@ -429,16 +420,16 @@
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'user_orders': [\u001b[0m\u001b[48;2;240;255;240m                                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 1, 'user_name': 'John Mcdonald', 'num_orders': 6},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 2, 'user_name': 'Jane Smith', 'num_orders': 4},\u001b[0m\u001b[48;2;240;255;240m                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 3, 'user_name': 'David Lee', 'num_orders': 2},\u001b[0m\u001b[48;2;240;255;240m                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 4, 'user_name': 'Rachelle Gonzalez', 'num_orders': 1},\u001b[0m\u001b[48;2;240;255;240m                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 5, 'user_name': 'Frank Anderson', 'num_orders': 3},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 6, 'user_name': 'Lisa Taylor', 'num_orders': 5},\u001b[0m\u001b[48;2;240;255;240m                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 7, 'user_name': 'Peter Wilson', 'num_orders': 7},\u001b[0m\u001b[48;2;240;255;240m                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 8, 'user_name': 'Micheal Harris', 'num_orders': 4},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 9, 'user_name': 'Sarah Anderson', 'num_orders': 2},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 10, 'user_name': 'Jessica Taylor', 'num_orders': 1}\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 3, 'user_name': 'Jane Smith', 'num_orders': 12},\u001b[0m\u001b[48;2;240;255;240m                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 1, 'user_name': 'Michael Jones', 'num_orders': 18},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 4, 'user_name': 'Mary Brown', 'num_orders': 9},\u001b[0m\u001b[48;2;240;255;240m                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 2, 'user_name': 'David Miller', 'num_orders': 21},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 5, 'user_name': 'Linda Martin', 'num_orders': 15},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 6, 'user_name': 'Robert Wilson', 'num_orders': 7},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 7, 'user_name': 'Jennifer Taylor', 'num_orders': 10},\u001b[0m\u001b[48;2;240;255;240m                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 8, 'user_name': 'Kevin Anderson', 'num_orders': 4},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 9, 'user_name': 'Sarah Thompson', 'num_orders': 23},\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'user_id': 10, 'user_name': 'Frank Davis', 'num_orders': 11}\u001b[0m\u001b[48;2;240;255;240m                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
@@ -472,7 +463,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.9"
+   "version": "3.12.1"
   }
  },
  "nbformat": 4,
diff --git a/docs/examples/guard_use.ipynb b/docs/examples/guard_use.ipynb
new file mode 100644
index 000000000..81e0ab6d7
--- /dev/null
+++ b/docs/examples/guard_use.ipynb
@@ -0,0 +1,125 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mregex_match...\u001b[0m\n",
+      "✅Successfully installed guardrails/regex_match!\n",
+      "\n",
+      "\n",
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mvalid_range...\u001b[0m\n",
+      "✅Successfully installed guardrails/valid_range!\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "! guardrails hub install hub://guardrails/regex_match --quiet\n",
+    "! guardrails hub install hub://guardrails/valid_range --quiet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pydantic import BaseModel, Field\n",
+    "from guardrails import Guard, OnFailAction\n",
+    "from guardrails.hub import RegexMatch, ValidRange\n",
+    "\n",
+    "class Person(BaseModel):\n",
+    "    name: str\n",
+    "    # Existing way of assigning validators\n",
+    "    age: int = Field(validators=[ValidRange(0, 100, on_fail=OnFailAction.EXCEPTION)])\n",
+    "    is_employed: bool"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Validation failed for field with errors: Value 101 is greater than 100.\n"
+     ]
+    }
+   ],
+   "source": [
+    "import json\n",
+    "from guardrails.errors import ValidationError\n",
+    "\n",
+    "\n",
+    "guard = Guard.from_pydantic(Person)\n",
+    "\n",
+    "try:\n",
+    "    guard.validate(json.dumps({\n",
+    "        \"name\": \"john doe\",\n",
+    "        \"age\": 101,\n",
+    "        \"is_employed\": False\n",
+    "    }))\n",
+    "except ValidationError as e:\n",
+    "    print(e)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Validation failed for field with errors: Result must match ^(?:[A-Z][^\\s]*\\s?)+$\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Now let's add a new validator to the name field\n",
+    "\n",
+    "guard.use(RegexMatch(\"^(?:[A-Z][^\\\\s]*\\\\s?)+$\", on_fail=OnFailAction.EXCEPTION), on=\"$.name\")\n",
+    "\n",
+    "try:\n",
+    "    guard.validate(json.dumps({\n",
+    "        \"name\": \"john doe\",\n",
+    "        \"age\": 30,\n",
+    "        \"is_employed\": True\n",
+    "    }))\n",
+    "except ValidationError as e:\n",
+    "    print(e)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.12.1"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/examples/guardrails_server.ipynb b/docs/examples/guardrails_server.ipynb
new file mode 100644
index 000000000..86d04bd11
--- /dev/null
+++ b/docs/examples/guardrails_server.ipynb
@@ -0,0 +1,334 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "! pip install \"guardrails-ai[api]==0.5.0a9\" -q"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "/Users/calebcourier/Projects/gr-mono/guardrails/docs/.venv/bin/guardrails\n"
+     ]
+    }
+   ],
+   "source": [
+    "! which guardrails"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mregex_match...\u001b[0m\n",
+      "✅Successfully installed guardrails/regex_match!\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "! guardrails hub install hub://guardrails/regex_match --quiet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Run this in a terminal\n",
+    "# guardrails start --config=./data/config.py"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "some-token\n",
+      "http://localhost:8000\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "\n",
+    "os.environ[\"GUARDRAILS_BASE_URL\"] = \"http://localhost:8000\"\n",
+    "\n",
+    "\n",
+    "print(os.environ.get(\"GUARDRAILS_BASE_URL\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
ValidationOutcome(\n",
+       "    call_id='5103958320',\n",
+       "    raw_llm_output='Guardrails AI',\n",
+       "    validated_output='Guardrails AI',\n",
+       "    reask=None,\n",
+       "    validation_passed=True,\n",
+       "    error=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'5103958320'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mvalidated_output\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidation_passed\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import logging\n", + "from rich import print\n", + "from guardrails import configure_logging\n", + "from guardrails import Guard, settings\n", + "\n", + "settings.use_server = True\n", + "configure_logging(None, log_level=logging.DEBUG)\n", + "\n", + "name_case = Guard(name='name-case')\n", + "\n", + "response = name_case.parse(\n", + " llm_output=\"Guardrails AI\"\n", + ")\n", + "\n", + "print(response)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
[\n",
+       "    Call(\n",
+       "        id='5103958320',\n",
+       "        iterations=[\n",
+       "            Iteration(\n",
+       "                id='5107862496',\n",
+       "                index=0,\n",
+       "                call_id='5103958320',\n",
+       "                inputs=Inputs(\n",
+       "                    llm_api=None,\n",
+       "                    llm_output='Guardrails AI',\n",
+       "                    instructions=None,\n",
+       "                    prompt=None,\n",
+       "                    msg_history=None,\n",
+       "                    prompt_params={},\n",
+       "                    num_reasks=0,\n",
+       "                    metadata={},\n",
+       "                    full_schema_reask=False,\n",
+       "                    stream=False\n",
+       "                ),\n",
+       "                outputs=Outputs(\n",
+       "                    llm_response_info=LLMResponse(\n",
+       "                        prompt_token_count=None,\n",
+       "                        response_token_count=None,\n",
+       "                        output='Guardrails AI',\n",
+       "                        stream_output=None,\n",
+       "                        async_stream_output=None\n",
+       "                    ),\n",
+       "                    raw_output=None,\n",
+       "                    parsed_output='Guardrails AI',\n",
+       "                    validation_response='Guardrails AI',\n",
+       "                    guarded_output='Guardrails AI',\n",
+       "                    reasks=[],\n",
+       "                    validator_logs=[\n",
+       "                        ValidatorLogs(\n",
+       "                            validator_name='RegexMatch',\n",
+       "                            registered_name='guardrails/regex_match',\n",
+       "                            instance_id=4636712336,\n",
+       "                            property_path='$',\n",
+       "                            value_before_validation='Guardrails AI',\n",
+       "                            value_after_validation='Guardrails AI',\n",
+       "                            validation_result=PassResult(\n",
+       "                                outcome='pass',\n",
+       "                                value_override=<class \n",
+       "'guardrails.classes.validation.validation_result.PassResult.ValueOverrideSentinel'>,\n",
+       "                                metadata=None,\n",
+       "                                validated_chunk=None\n",
+       "                            ),\n",
+       "                            start_time=datetime.datetime(2024, 6, 27, 14, 14, 20, 649099),\n",
+       "                            end_time=datetime.datetime(2024, 6, 27, 14, 14, 20, 651227)\n",
+       "                        )\n",
+       "                    ],\n",
+       "                    error=None,\n",
+       "                    exception=None\n",
+       "                )\n",
+       "            )\n",
+       "        ],\n",
+       "        inputs=CallInputs(\n",
+       "            llm_api=None,\n",
+       "            llm_output=None,\n",
+       "            instructions=None,\n",
+       "            prompt=None,\n",
+       "            msg_history=None,\n",
+       "            prompt_params={},\n",
+       "            num_reasks=0,\n",
+       "            metadata={},\n",
+       "            full_schema_reask=False,\n",
+       "            stream=False,\n",
+       "            args=[],\n",
+       "            kwargs={'api_key': '***********************************************69ck'}\n",
+       "        ),\n",
+       "        exception=None\n",
+       "    )\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m[\u001b[0m\n", + " \u001b[1;35mCall\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mid\u001b[0m=\u001b[32m'5103958320'\u001b[0m,\n", + " \u001b[33miterations\u001b[0m=\u001b[1m[\u001b[0m\n", + " \u001b[1;35mIteration\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mid\u001b[0m=\u001b[32m'5107862496'\u001b[0m,\n", + " \u001b[33mindex\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'5103958320'\u001b[0m,\n", + " \u001b[33minputs\u001b[0m=\u001b[1;35mInputs\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mllm_api\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mllm_output\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33minstructions\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mprompt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mmsg_history\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mprompt_params\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mnum_reasks\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mfull_schema_reask\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + " \u001b[33mstream\u001b[0m=\u001b[3;91mFalse\u001b[0m\n", + " \u001b[1m)\u001b[0m,\n", + " \u001b[33moutputs\u001b[0m=\u001b[1;35mOutputs\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mllm_response_info\u001b[0m=\u001b[1;35mLLMResponse\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mprompt_token_count\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mresponse_token_count\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33moutput\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mstream_output\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33masync_stream_output\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + " \u001b[1m)\u001b[0m,\n", + " \u001b[33mraw_output\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mparsed_output\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mvalidation_response\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mguarded_output\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mreasks\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[33mvalidator_logs\u001b[0m=\u001b[1m[\u001b[0m\n", + " \u001b[1;35mValidatorLogs\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mvalidator_name\u001b[0m=\u001b[32m'RegexMatch'\u001b[0m,\n", + " \u001b[33mregistered_name\u001b[0m=\u001b[32m'guardrails/regex_match'\u001b[0m,\n", + " \u001b[33minstance_id\u001b[0m=\u001b[1;36m4636712336\u001b[0m,\n", + " \u001b[33mproperty_path\u001b[0m=\u001b[32m'$'\u001b[0m,\n", + " \u001b[33mvalue_before_validation\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mvalue_after_validation\u001b[0m=\u001b[32m'Guardrails AI'\u001b[0m,\n", + " \u001b[33mvalidation_result\u001b[0m=\u001b[1;35mPassResult\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33moutcome\u001b[0m=\u001b[32m'pass'\u001b[0m,\n", + " \u001b[33mvalue_override\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\n", + "\u001b[32m'guardrails.classes.validation.validation_result.PassResult.ValueOverrideSentinel'\u001b[0m\u001b[1m>\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidated_chunk\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + " \u001b[1m)\u001b[0m,\n", + " \u001b[33mstart_time\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2024\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m27\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m649099\u001b[0m\u001b[1m)\u001b[0m,\n", + " \u001b[33mend_time\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2024\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m27\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m651227\u001b[0m\u001b[1m)\u001b[0m\n", + " \u001b[1m)\u001b[0m\n", + " \u001b[1m]\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mexception\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + " \u001b[1m)\u001b[0m\n", + " \u001b[1m)\u001b[0m\n", + " \u001b[1m]\u001b[0m,\n", + " \u001b[33minputs\u001b[0m=\u001b[1;35mCallInputs\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mllm_api\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mllm_output\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33minstructions\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mprompt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mmsg_history\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mprompt_params\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mnum_reasks\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mfull_schema_reask\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + " \u001b[33mstream\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + " \u001b[33margs\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[33mkwargs\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'api_key'\u001b[0m: \u001b[32m'***********************************************69ck'\u001b[0m\u001b[1m}\u001b[0m\n", + " \u001b[1m)\u001b[0m,\n", + " \u001b[33mexception\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + " \u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(name_case.history)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/guardrails_with_chat_models.ipynb b/docs/examples/guardrails_with_chat_models.ipynb index d26409b4e..befe79cba 100644 --- a/docs/examples/guardrails_with_chat_models.ipynb +++ b/docs/examples/guardrails_with_chat_models.ipynb @@ -20,7 +20,12 @@ "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mone_line...\u001b[0m\n", "✅Successfully installed guardrails/one_line!\n", "\n", - "\n" + "\n", + "Requirement already satisfied: pypdfium2 in /Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages (4.30.0)\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.2\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n" ] } ], @@ -64,7 +69,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/pypdfium2/_helpers/textpage.py:80: UserWarning: get_text_range() call with default params will be implicitly redirected to get_text_bounded()\n", + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pypdfium2/_helpers/textpage.py:80: UserWarning: get_text_range() call with default params will be implicitly redirected to get_text_bounded()\n", " warnings.warn(\"get_text_range() call with default params will be implicitly redirected to get_text_bounded()\")\n" ] }, @@ -248,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -302,23 +307,15 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/guardrails/validators/__init__.py:51: FutureWarning: \n", - " Importing validators from `guardrails.validators` is deprecated.\n", - " All validators are now available in the Guardrails Hub. Please install\n", - " and import them from the hub instead. All validators will be\n", - " removed from this module in the next major release.\n", - "\n", - " Install with: `guardrails hub install hub:///`\n", - " Import as: from guardrails.hub import `ValidatorName`\n", - " \n", - " warn(\n" + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", + " from tqdm.autonotebook import tqdm, trange\n" ] } ], @@ -331,7 +328,7 @@ "\n", "${document}\n", "\n", - "${gr.complete_json_suffix_v2}\n", + "${gr.complete_xml_suffix_v2}\n", "\"\"\"\n", "\n", "class Fee(BaseModel):\n", @@ -370,29 +367,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/guardrails/validatorsattr.py:307: UserWarning: Validator 1-indexed is not installed!\n", - " warnings.warn(f\"Validator {validator_name} is not installed!\")\n", - "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/guardrails/validatorsattr.py:307: UserWarning: Validator hub is not installed!\n", - " warnings.warn(f\"Validator {validator_name} is not installed!\")\n", - "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/guardrails/validator_base.py:410: FutureWarning: Accessing `OneLine` using\n", - "`from guardrails.validators import OneLine` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import OneLine` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/one_line.\n", - "\n", - " warn(\n", - "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/guardrails/validatorsattr.py:307: UserWarning: Validator percentage is not installed!\n", - " warnings.warn(f\"Validator {validator_name} is not installed!\")\n" - ] - } - ], + "outputs": [], "source": [ "guard = gd.Guard.from_rail_string(rail_str)" ] @@ -406,35 +383,51 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "guard = gd.Guard.from_pydantic(output_class=CreditCardAgreement, prompt=prompt)" + "guard = gd.Guard.from_pydantic(output_class=CreditCardAgreement)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "As we can see, a few formatters weren't supported. These formatters won't be enforced in the output, but this information can still be used to generate a prompt.\n", + "As we can see, a few formatters weren't supported. These formatters won't be enforced in the output, but this information can still be used to generate a prompt." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", "\n", - "We see the prompt that will be sent to the LLM. The `{document}` is substituted with the user provided value at runtime." + "raw_llm_response, validated_response, *rest = guard(\n", + " model=\"gpt-4o\",\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={\"document\": content[:6000]},\n", + " max_tokens=2048,\n", + " temperature=0,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see in the prompt that was sent to the LLM, the `{document}` is substituted with the user provided value at runtime." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/c8/jqt82fpx785dpwpp36ljkgm40000gn/T/ipykernel_82182/3983563700.py:1: DeprecationWarning: 'Guard.base_prompt' is deprecated and will be removed in versions 0.5.x and beyond. Use 'Guard.history.last.prompt' instead.\n", - " print(guard.base_prompt)\n" - ] - }, { "data": { "text/html": [ @@ -442,29 +435,137 @@ "Given the following document, answer the following questions. If the answer doesn't exist in the document, enter \n", "'None'.\n", "\n", - "${document}\n", + "2/25/23, 7:59 PM about:blank\n", + "about:blank 1/4\n", + "PRICING INFORMATION\n", + "INTEREST RATES AND INTEREST CHARGES\n", + "Purchase Annual\n", + "Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.\n", + "After that, 19.49%. This APR will vary with the market based on the Prime\n", + "Rate.\n", + "a\n", + "My Chase Loan\n", + "SM APR 19.49%. This APR will vary with the market based on the Prime Rate.\n", + "a\n", + "Promotional offers with fixed APRs and varying durations may be available from\n", + "time to time on some accounts.\n", + "Balance Transfer APR 0% Intro APR for the first 18 months that your Account is open.\n", + "After that, 19.49%. This APR will vary with the market based on the Prime\n", + "Rate.\n", + "a\n", + "Cash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.\n", + "b\n", + "Penalty APR and When\n", + "It Applies\n", + "Up to 29.99%. This APR will vary with the market based on the Prime Rate.\n", + "c\n", + "We may apply the Penalty APR to your account if you:\n", + "fail to make a Minimum Payment by the date and time that it is due; or\n", + "make a payment to us that is returned unpaid.\n", + "How Long Will the Penalty APR Apply?: If we apply the Penalty APR for\n", + "either of these reasons, the Penalty APR could potentially remain in effect\n", + "indefinitely.\n", + "How to Avoid Paying\n", + "Interest on Purchases\n", + "Your due date will be a minimum of 21 days after the close of each billing cycle.\n", + "We will not charge you interest on new purchases if you pay your entire balance\n", + "or Interest Saving Balance by the due date each month. We will begin charging\n", + "interest on balance transfers and cash advances on the transaction date.\n", + "Minimum Interest\n", + "Charge\n", + "None\n", + "Credit Card Tips from\n", + "the Consumer Financial\n", + "Protection Bureau\n", + "To learn more about factors to consider when applying for or using a credit card,\n", + "visit the website of the Consumer Financial Protection Bureau at\n", + "http://www.consumerfinance.gov/learnmore.\n", + "FEES\n", + "Annual Membership\n", + "Fee\n", + "None\n", + "My Chase Plan\n", + "SM Fee\n", + "(fixed finance charge)\n", + "Monthly fee of 0% of the amount of each eligible purchase transaction or\n", + "amount selected to create a My Chase Plan while in the 0% Intro Purchase\n", + "APR period.\n", + "After that, monthly fee of 1.72% of the amount of each eligible purchase\n", + "transaction or amount selected to create a My Chase Plan. The My Chase Plan\n", + "Fee will be determined at the time each My Chase Plan is created and will\n", + "remain the same until the My Chase Plan is paid in full.\n", + "d\n", + "Transaction Fees\n", + "Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater,\n", + "on transfers made within 60 days of account opening. After that: Either $5 or 5%\n", + "of the amount of each transfer, whichever is greater.\n", + "Cash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.\n", + "2/25/23, 7:59 PM about:blank\n", + "about:blank 2/4\n", + "Foreign Transactions 3% of the amount of each transaction in U.S. dollars.\n", + "Penalty Fees\n", + "Late Payment Up to $40.\n", + "Over-the-Credit-Limit None\n", + "Return Payment Up to $40.\n", + "Return Check None\n", + "Note: This account may not be eligible for balance transfers.\n", + "Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60 days late, and\n", + "apply the Penalty APR.\n", + "How We Will Calculate Your Balance: We use the daily balance method (including new transactions).\n", + "Prime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.\n", + "aWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.\n", + "Maximum APR 29.99%.\n", + "bWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.\n", + "cWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.\n", + "dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based on\n", + "the amount of each purchase transaction or amount selected to create the plan, the number of billing periods\n", + "you choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of your My\n", + "Chase Plan Fee will be disclosed during the activation of each My Chase Plan.\n", + "MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed\n", + "Forces and their dependents relating to extensions of consumer credit. In general, the cost of consumer credit\n", + "to a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of 36\n", + "percent. This rate must include, as applicable to the credit transaction or account: the costs associated with\n", + "credit insurance premiums; fees for ancillary products sold in connection with the credit transaction; any\n", + "application fee charged (other than certain application fees for specified credit transactions or accounts); and\n", + "any participation fee charged (other than certain participation fees for a credit card account). To receive this\n", + "information and a description of your payment obligation verbally, please call 1-800-235-9978.\n", + "TERMS & CONDITIONS\n", + "Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC, a\n", + "subsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:\n", + "1. You authorize us to obtain credit bureau reports, employment, and income information about you that we\n", + "will use when considering your application for credit. We may obtain and use information about your\n", + "accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit\n", + "bureaus and other entities. You also authorize us to obtain credit bureau reports and any other\n", + "information about you in connection with: 1) extensions of credit on your account; 2) the administration,\n", + "review or collection of your account; and 3) offering you enhanced or additional products and services. If\n", + "you ask, we will tell you the name and address of the credit bureau from which we obtained a report\n", + "about you.\n", + "2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You agree to the\n", + "terms of this agreement by: using the account or any card, authorizing their use, or making any payment\n", + "on the account.\n", + "3. By providing your mobile ph\n", "\n", "\n", "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "<output>\n", - " <list name=\"fees\" description=\"What fees and charges are associated with my account?\">\n", - " <object>\n", - " <string name=\"name\" format=\"guardrails/lowercase; guardrails/two_words\"/>\n", - " <string name=\"explanation\" format=\"guardrails/one_line\"/>\n", - " <float name=\"value\" description=\"The fee amount in USD or as a percentage.\"/>\n", - " </object>\n", - " </list>\n", - " <list name=\"interest_rates\" description=\"What are the interest rates offered by the bank on different kinds of \n", - "accounts and products?\">\n", - " <object>\n", - " <string name=\"account_type\" format=\"guardrails/lowercase\"/>\n", - " <float name=\"rate\" description=\"The annual percentage rate (APR) for the account type.\"/>\n", - " </object>\n", - " </list>\n", + " <list description=\"What fees and charges are associated with my account?\" name=\"fees\" required=\"true\">\n", + " <object required=\"true\">\n", + " <string format=\"guardrails/lowercase; guardrails/two_words\" name=\"name\" required=\"true\"></string>\n", + " <string format=\"guardrails/one_line\" name=\"explanation\" required=\"true\"></string>\n", + " <float description=\"The fee amount in USD or as a percentage.\" name=\"value\" required=\"true\"></float>\n", + " </object>\n", + " </list>\n", + " <list description=\"What are the interest rates offered by the bank on different kinds of accounts and products?\" \n", + "name=\"interest_rates\" required=\"true\">\n", + " <object required=\"true\">\n", + " <string format=\"guardrails/lowercase\" name=\"account_type\" required=\"true\"></string>\n", + " <float description=\"The annual percentage rate (APR) for the account type.\" name=\"rate\" \n", + "required=\"true\"></float>\n", + " </object>\n", + " </list>\n", "</output>\n", "\n", - "\n", "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n", "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n", "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n", @@ -484,29 +585,137 @@ "Given the following document, answer the following questions. If the answer doesn't exist in the document, enter \n", "\u001b[32m'None'\u001b[0m.\n", "\n", - "$\u001b[1m{\u001b[0mdocument\u001b[1m}\u001b[0m\n", + "\u001b[1;36m2\u001b[0m/\u001b[1;36m25\u001b[0m/\u001b[1;36m23\u001b[0m, \u001b[1;92m7:59\u001b[0m PM about:blank\n", + "about:blank \u001b[1;36m1\u001b[0m/\u001b[1;36m4\u001b[0m\n", + "PRICING INFORMATION\n", + "INTEREST RATES AND INTEREST CHARGES\n", + "Purchase Annual\n", + "Percentage Rate \u001b[1m(\u001b[0mAPR\u001b[1m)\u001b[0m \u001b[1;36m0\u001b[0m% Intro APR for the first \u001b[1;36m18\u001b[0m months that your Account is open.\n", + "After that, \u001b[1;36m19.49\u001b[0m%. This APR will vary with the market based on the Prime\n", + "Rate.\n", + "a\n", + "My Chase Loan\n", + "SM APR \u001b[1;36m19.49\u001b[0m%. This APR will vary with the market based on the Prime Rate.\n", + "a\n", + "Promotional offers with fixed APRs and varying durations may be available from\n", + "time to time on some accounts.\n", + "Balance Transfer APR \u001b[1;36m0\u001b[0m% Intro APR for the first \u001b[1;36m18\u001b[0m months that your Account is open.\n", + "After that, \u001b[1;36m19.49\u001b[0m%. This APR will vary with the market based on the Prime\n", + "Rate.\n", + "a\n", + "Cash Advance APR \u001b[1;36m29.49\u001b[0m%. This APR will vary with the market based on the Prime Rate.\n", + "b\n", + "Penalty APR and When\n", + "It Applies\n", + "Up to \u001b[1;36m29.99\u001b[0m%. This APR will vary with the market based on the Prime Rate.\n", + "c\n", + "We may apply the Penalty APR to your account if you:\n", + "fail to make a Minimum Payment by the date and time that it is due; or\n", + "make a payment to us that is returned unpaid.\n", + "How Long Will the Penalty APR Apply?: If we apply the Penalty APR for\n", + "either of these reasons, the Penalty APR could potentially remain in effect\n", + "indefinitely.\n", + "How to Avoid Paying\n", + "Interest on Purchases\n", + "Your due date will be a minimum of \u001b[1;36m21\u001b[0m days after the close of each billing cycle.\n", + "We will not charge you interest on new purchases if you pay your entire balance\n", + "or Interest Saving Balance by the due date each month. We will begin charging\n", + "interest on balance transfers and cash advances on the transaction date.\n", + "Minimum Interest\n", + "Charge\n", + "\u001b[3;35mNone\u001b[0m\n", + "Credit Card Tips from\n", + "the Consumer Financial\n", + "Protection Bureau\n", + "To learn more about factors to consider when applying for or using a credit card,\n", + "visit the website of the Consumer Financial Protection Bureau at\n", + "\u001b[4;94mhttp://www.consumerfinance.gov/learnmore.\u001b[0m\n", + "FEES\n", + "Annual Membership\n", + "Fee\n", + "\u001b[3;35mNone\u001b[0m\n", + "My Chase Plan\n", + "SM Fee\n", + "\u001b[1m(\u001b[0mfixed finance charge\u001b[1m)\u001b[0m\n", + "Monthly fee of \u001b[1;36m0\u001b[0m% of the amount of each eligible purchase transaction or\n", + "amount selected to create a My Chase Plan while in the \u001b[1;36m0\u001b[0m% Intro Purchase\n", + "APR period.\n", + "After that, monthly fee of \u001b[1;36m1.72\u001b[0m% of the amount of each eligible purchase\n", + "transaction or amount selected to create a My Chase Plan. The My Chase Plan\n", + "Fee will be determined at the time each My Chase Plan is created and will\n", + "remain the same until the My Chase Plan is paid in full.\n", + "d\n", + "Transaction Fees\n", + "Balance Transfers Intro fee of either $\u001b[1;36m5\u001b[0m or \u001b[1;36m3\u001b[0m% of the amount of each transfer, whichever is greater,\n", + "on transfers made within \u001b[1;36m60\u001b[0m days of account opening. After that: Either $\u001b[1;36m5\u001b[0m or \u001b[1;36m5\u001b[0m%\n", + "of the amount of each transfer, whichever is greater.\n", + "Cash Advances Either $\u001b[1;36m10\u001b[0m or \u001b[1;36m5\u001b[0m% of the amount of each transaction, whichever is greater.\n", + "\u001b[1;36m2\u001b[0m/\u001b[1;36m25\u001b[0m/\u001b[1;36m23\u001b[0m, \u001b[1;92m7:59\u001b[0m PM about:blank\n", + "about:blank \u001b[1;36m2\u001b[0m/\u001b[1;36m4\u001b[0m\n", + "Foreign Transactions \u001b[1;36m3\u001b[0m% of the amount of each transaction in U.S. dollars.\n", + "Penalty Fees\n", + "Late Payment Up to $\u001b[1;36m40\u001b[0m.\n", + "Over-the-Credit-Limit \u001b[3;35mNone\u001b[0m\n", + "Return Payment Up to $\u001b[1;36m40\u001b[0m.\n", + "Return Check \u001b[3;35mNone\u001b[0m\n", + "Note: This account may not be eligible for balance transfers.\n", + "Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is \u001b[1;36m60\u001b[0m days late, and\n", + "apply the Penalty APR.\n", + "How We Will Calculate Your Balance: We use the daily balance method \u001b[1m(\u001b[0mincluding new transactions\u001b[1m)\u001b[0m.\n", + "Prime Rate: Variable APRs are based on the \u001b[1;36m7.75\u001b[0m% Prime Rate as of \u001b[1;36m2\u001b[0m/\u001b[1;36m7\u001b[0m/\u001b[1;36m2023\u001b[0m.\n", + "aWe add \u001b[1;36m11.74\u001b[0m% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.\n", + "Maximum APR \u001b[1;36m29.99\u001b[0m%.\n", + "bWe add \u001b[1;36m21.74\u001b[0m% to the Prime Rate to determine the Cash Advance APR. Maximum APR \u001b[1;36m29.99\u001b[0m%.\n", + "cWe add up to \u001b[1;36m26.99\u001b[0m% to the Prime Rate to determine the Penalty APR. Maximum APR \u001b[1;36m29.99\u001b[0m%.\n", + "dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based on\n", + "the amount of each purchase transaction or amount selected to create the plan, the number of billing periods\n", + "you choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of your My\n", + "Chase Plan Fee will be disclosed during the activation of each My Chase Plan.\n", + "MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed\n", + "Forces and their dependents relating to extensions of consumer credit. In general, the cost of consumer credit\n", + "to a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of \u001b[1;36m36\u001b[0m\n", + "percent. This rate must include, as applicable to the credit transaction or account: the costs associated with\n", + "credit insurance premiums; fees for ancillary products sold in connection with the credit transaction; any\n", + "application fee charged \u001b[1m(\u001b[0mother than certain application fees for specified credit transactions or accounts\u001b[1m)\u001b[0m; and\n", + "any participation fee charged \u001b[1m(\u001b[0mother than certain participation fees for a credit card account\u001b[1m)\u001b[0m. To receive this\n", + "information and a description of your payment obligation verbally, please call \u001b[1;36m1\u001b[0m-\u001b[1;36m800\u001b[0m-\u001b[1;36m235\u001b[0m-\u001b[1;36m9978\u001b[0m.\n", + "TERMS & CONDITIONS\n", + "Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC, a\n", + "subsidiary of JPMorgan Chase & Co. \u001b[1m(\u001b[0m\u001b[32m\"Chase\"\u001b[0m, \u001b[32m\"we\"\u001b[0m, or \u001b[32m\"us\"\u001b[0m\u001b[1m)\u001b[0m, you agree to the following:\n", + "\u001b[1;36m1\u001b[0m. You authorize us to obtain credit bureau reports, employment, and income information about you that we\n", + "will use when considering your application for credit. We may obtain and use information about your\n", + "accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit\n", + "bureaus and other entities. You also authorize us to obtain credit bureau reports and any other\n", + "information about you in connection with: \u001b[1;36m1\u001b[0m\u001b[1m)\u001b[0m extensions of credit on your account; \u001b[1;36m2\u001b[0m\u001b[1m)\u001b[0m the administration,\n", + "review or collection of your account; and \u001b[1;36m3\u001b[0m\u001b[1m)\u001b[0m offering you enhanced or additional products and services. If\n", + "you ask, we will tell you the name and address of the credit bureau from which we obtained a report\n", + "about you.\n", + "\u001b[1;36m2\u001b[0m. If an account is opened, you will receive a Cardmember Agreement with your \u001b[1;35mcard\u001b[0m\u001b[1m(\u001b[0ms\u001b[1m)\u001b[0m. You agree to the\n", + "terms of this agreement by: using the account or any card, authorizing their use, or making any payment\n", + "on the account.\n", + "\u001b[1;36m3\u001b[0m. By providing your mobile ph\n", "\n", "\n", "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mfloat\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mfloat\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", "\n", - "\n", "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", @@ -526,31 +735,7 @@ } ], "source": [ - "print(guard.base_prompt)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here's the formatted instructions sent as the system message to the LLM." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", - " prompt_params={\"document\": content[:6000]},\n", - " max_tokens=2048,\n", - " temperature=0,\n", - ")" + "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])" ] }, { @@ -564,7 +749,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -577,33 +762,33 @@ " 'name': 'my chase',\n", " 'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or amount \n", "selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee of 1.72% of \n", - "the amount of each eligible purchase transaction or amount selected to create a My Chase Plan. The My Chase Plan \n", - "Fee will be determined at the time each My Chase Plan is created and will remain the same until the My Chase Plan \n", - "is paid in full.',\n", + "the amount of each eligible purchase transaction or amount selected to create a My Chase Plan.',\n", " 'value': 0.0\n", " },\n", " {\n", - " 'name': 'transaction fees',\n", - " 'explanation': 'Balance Transfers: Intro fee of either $5 or 3% of the amount of each transfer, \n", - "whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the \n", - "amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the amount of each transaction, \n", + " 'name': 'balance transfers',\n", + " 'explanation': 'Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater, on \n", + "transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each transfer, \n", "whichever is greater.',\n", - " 'value': 0.0\n", + " 'value': 5.0\n", " },\n", " {\n", - " 'name': 'foreign transactions',\n", - " 'explanation': '3% of the amount of each transaction in U.S. dollars',\n", - " 'value': 0.0\n", + " 'name': 'cash advances',\n", + " 'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.',\n", + " 'value': 10.0\n", " },\n", " {\n", - " 'name': 'penalty fees',\n", - " 'explanation': 'Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to $40. Return\n", - "Check: None',\n", - " 'value': 0.0\n", - " }\n", + " 'name': 'foreign transactions',\n", + " 'explanation': '3% of the amount of each transaction in U.S. dollars.',\n", + " 'value': 3.0\n", + " },\n", + " {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},\n", + " {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0}\n", " ],\n", " 'interest_rates': [\n", - " {'account_type': 'purchase/my chase loan/balance transfer', 'rate': 19.49},\n", + " {'account_type': 'purchase', 'rate': 19.49},\n", + " {'account_type': 'my chase loan', 'rate': 19.49},\n", + " {'account_type': 'balance transfer', 'rate': 19.49},\n", " {'account_type': 'cash advance', 'rate': 29.49},\n", " {'account_type': 'penalty', 'rate': 29.99}\n", " ]\n", @@ -618,33 +803,33 @@ " \u001b[32m'name'\u001b[0m: \u001b[32m'my chase'\u001b[0m,\n", " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Monthly fee of 0% of the amount of each eligible purchase transaction or amount \u001b[0m\n", "\u001b[32mselected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee of 1.72% of \u001b[0m\n", - "\u001b[32mthe amount of each eligible purchase transaction or amount selected to create a My Chase Plan. The My Chase Plan \u001b[0m\n", - "\u001b[32mFee will be determined at the time each My Chase Plan is created and will remain the same until the My Chase Plan \u001b[0m\n", - "\u001b[32mis paid in full.'\u001b[0m,\n", + "\u001b[32mthe amount of each eligible purchase transaction or amount selected to create a My Chase Plan.'\u001b[0m,\n", " \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", - " \u001b[32m'name'\u001b[0m: \u001b[32m'transaction fees'\u001b[0m,\n", - " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Balance Transfers: Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\n", - "\u001b[32mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the \u001b[0m\n", - "\u001b[32mamount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the amount of each transaction, \u001b[0m\n", + " \u001b[32m'name'\u001b[0m: \u001b[32m'balance transfers'\u001b[0m,\n", + " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater, on \u001b[0m\n", + "\u001b[32mtransfers made within 60 days of account opening. After that: Either $5 or 5% of the amount of each transfer, \u001b[0m\n", "\u001b[32mwhichever is greater.'\u001b[0m,\n", - " \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", + " \u001b[32m'value'\u001b[0m: \u001b[1;36m5.0\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", - " \u001b[32m'name'\u001b[0m: \u001b[32m'foreign transactions'\u001b[0m,\n", - " \u001b[32m'explanation'\u001b[0m: \u001b[32m'3% of the amount of each transaction in U.S. dollars'\u001b[0m,\n", - " \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", + " \u001b[32m'name'\u001b[0m: \u001b[32m'cash advances'\u001b[0m,\n", + " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Either $10 or 5% of the amount of each transaction, whichever is greater.'\u001b[0m,\n", + " \u001b[32m'value'\u001b[0m: \u001b[1;36m10.0\u001b[0m\n", " \u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\n", - " \u001b[32m'name'\u001b[0m: \u001b[32m'penalty fees'\u001b[0m,\n", - " \u001b[32m'explanation'\u001b[0m: \u001b[32m'Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to $40. Return\u001b[0m\n", - "\u001b[32mCheck: None'\u001b[0m,\n", - " \u001b[32m'value'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", - " \u001b[1m}\u001b[0m\n", + " \u001b[32m'name'\u001b[0m: \u001b[32m'foreign transactions'\u001b[0m,\n", + " \u001b[32m'explanation'\u001b[0m: \u001b[32m'3% of the amount of each transaction in U.S. dollars.'\u001b[0m,\n", + " \u001b[32m'value'\u001b[0m: \u001b[1;36m3.0\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'late payment'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'Up to $40.'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m40.0\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\u001b[32m'name'\u001b[0m: \u001b[32m'return payment'\u001b[0m, \u001b[32m'explanation'\u001b[0m: \u001b[32m'Up to $40.'\u001b[0m, \u001b[32m'value'\u001b[0m: \u001b[1;36m40.0\u001b[0m\u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m,\n", " \u001b[32m'interest_rates'\u001b[0m: \u001b[1m[\u001b[0m\n", - " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'purchase/my chase loan/balance transfer'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m19.49\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'purchase'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m19.49\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'my chase loan'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m19.49\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'balance transfer'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m19.49\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'cash advance'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m29.49\u001b[0m\u001b[1m}\u001b[0m,\n", " \u001b[1m{\u001b[0m\u001b[32m'account_type'\u001b[0m: \u001b[32m'penalty'\u001b[0m, \u001b[32m'rate'\u001b[0m: \u001b[1;36m29.99\u001b[0m\u001b[1m}\u001b[0m\n", " \u001b[1m]\u001b[0m\n", @@ -661,393 +846,204 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Logs\n",
-       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Given the following document, answer the following questions. If the answer doesn't exist in the        │ │\n",
-       "│   │ │ document, enter 'None'.                                                                                 │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ 2/25/23, 7:59 PM about:blank                                                                            │ │\n",
-       "│   │ │ about:blank 1/4                                                                                         │ │\n",
-       "│   │ │ PRICING INFORMATION                                                                                     │ │\n",
-       "│   │ │ INTEREST RATES AND INTEREST CHARGES                                                                     │ │\n",
-       "│   │ │ Purchase Annual                                                                                         │ │\n",
-       "│   │ │ Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.                   │ │\n",
-       "│   │ │ After that, 19.49%. This APR will vary with the market based on the Prime                               │ │\n",
-       "│   │ │ Rate.                                                                                                   │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ My Chase Loan                                                                                           │ │\n",
-       "│   │ │ SM APR 19.49%. This APR will vary with the market based on the Prime Rate.                              │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ Promotional offers with fixed APRs and varying durations may be available from                          │ │\n",
-       "│   │ │ time to time on some accounts.                                                                          │ │\n",
-       "│   │ │ Balance Transfer APR 0% Intro APR for the first 18 months that your Account is open.                    │ │\n",
-       "│   │ │ After that, 19.49%. This APR will vary with the market based on the Prime                               │ │\n",
-       "│   │ │ Rate.                                                                                                   │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ Cash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.                    │ │\n",
-       "│   │ │ b                                                                                                       │ │\n",
-       "│   │ │ Penalty APR and When                                                                                    │ │\n",
-       "│   │ │ It Applies                                                                                              │ │\n",
-       "│   │ │ Up to 29.99%. This APR will vary with the market based on the Prime Rate.                               │ │\n",
-       "│   │ │ c                                                                                                       │ │\n",
-       "│   │ │ We may apply the Penalty APR to your account if you:                                                    │ │\n",
-       "│   │ │ fail to make a Minimum Payment by the date and time that it is due; or                                  │ │\n",
-       "│   │ │ make a payment to us that is returned unpaid.                                                           │ │\n",
-       "│   │ │ How Long Will the Penalty APR Apply?: If we apply the Penalty APR for                                   │ │\n",
-       "│   │ │ either of these reasons, the Penalty APR could potentially remain in effect                             │ │\n",
-       "│   │ │ indefinitely.                                                                                           │ │\n",
-       "│   │ │ How to Avoid Paying                                                                                     │ │\n",
-       "│   │ │ Interest on Purchases                                                                                   │ │\n",
-       "│   │ │ Your due date will be a minimum of 21 days after the close of each billing cycle.                       │ │\n",
-       "│   │ │ We will not charge you interest on new purchases if you pay your entire balance                         │ │\n",
-       "│   │ │ or Interest Saving Balance by the due date each month. We will begin charging                           │ │\n",
-       "│   │ │ interest on balance transfers and cash advances on the transaction date.                                │ │\n",
-       "│   │ │ Minimum Interest                                                                                        │ │\n",
-       "│   │ │ Charge                                                                                                  │ │\n",
-       "│   │ │ None                                                                                                    │ │\n",
-       "│   │ │ Credit Card Tips from                                                                                   │ │\n",
-       "│   │ │ the Consumer Financial                                                                                  │ │\n",
-       "│   │ │ Protection Bureau                                                                                       │ │\n",
-       "│   │ │ To learn more about factors to consider when applying for or using a credit card,                       │ │\n",
-       "│   │ │ visit the website of the Consumer Financial Protection Bureau at                                        │ │\n",
-       "│   │ │ http://www.consumerfinance.gov/learnmore.                                                               │ │\n",
-       "│   │ │ FEES                                                                                                    │ │\n",
-       "│   │ │ Annual Membership                                                                                       │ │\n",
-       "│   │ │ Fee                                                                                                     │ │\n",
-       "│   │ │ None                                                                                                    │ │\n",
-       "│   │ │ My Chase Plan                                                                                           │ │\n",
-       "│   │ │ SM Fee                                                                                                  │ │\n",
-       "│   │ │ (fixed finance charge)                                                                                  │ │\n",
-       "│   │ │ Monthly fee of 0% of the amount of each eligible purchase transaction or                                │ │\n",
-       "│   │ │ amount selected to create a My Chase Plan while in the 0% Intro Purchase                                │ │\n",
-       "│   │ │ APR period.                                                                                             │ │\n",
-       "│   │ │ After that, monthly fee of 1.72% of the amount of each eligible purchase                                │ │\n",
-       "│   │ │ transaction or amount selected to create a My Chase Plan. The My Chase Plan                             │ │\n",
-       "│   │ │ Fee will be determined at the time each My Chase Plan is created and will                               │ │\n",
-       "│   │ │ remain the same until the My Chase Plan is paid in full.                                                │ │\n",
-       "│   │ │ d                                                                                                       │ │\n",
-       "│   │ │ Transaction Fees                                                                                        │ │\n",
-       "│   │ │ Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater,    │ │\n",
-       "│   │ │ on transfers made within 60 days of account opening. After that: Either $5 or 5%                        │ │\n",
-       "│   │ │ of the amount of each transfer, whichever is greater.                                                   │ │\n",
-       "│   │ │ Cash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.                 │ │\n",
-       "│   │ │ 2/25/23, 7:59 PM about:blank                                                                            │ │\n",
-       "│   │ │ about:blank 2/4                                                                                         │ │\n",
-       "│   │ │ Foreign Transactions 3% of the amount of each transaction in U.S. dollars.                              │ │\n",
-       "│   │ │ Penalty Fees                                                                                            │ │\n",
-       "│   │ │ Late Payment Up to $40.                                                                                 │ │\n",
-       "│   │ │ Over-the-Credit-Limit None                                                                              │ │\n",
-       "│   │ │ Return Payment Up to $40.                                                                               │ │\n",
-       "│   │ │ Return Check None                                                                                       │ │\n",
-       "│   │ │ Note: This account may not be eligible for balance transfers.                                           │ │\n",
-       "│   │ │ Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60 days late,   │ │\n",
-       "│   │ │ and                                                                                                     │ │\n",
-       "│   │ │ apply the Penalty APR.                                                                                  │ │\n",
-       "│   │ │ How We Will Calculate Your Balance: We use the daily balance method (including new transactions).       │ │\n",
-       "│   │ │ Prime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.                             │ │\n",
-       "│   │ │ aWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.          │ │\n",
-       "│   │ │ Maximum APR 29.99%.                                                                                     │ │\n",
-       "│   │ │ bWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.                 │ │\n",
-       "│   │ │ cWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.                │ │\n",
-       "│   │ │ dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based   │ │\n",
-       "│   │ │ on                                                                                                      │ │\n",
-       "│   │ │ the amount of each purchase transaction or amount selected to create the plan, the number of billing    │ │\n",
-       "│   │ │ periods                                                                                                 │ │\n",
-       "│   │ │ you choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of    │ │\n",
-       "│   │ │ your My                                                                                                 │ │\n",
-       "│   │ │ Chase Plan Fee will be disclosed during the activation of each My Chase Plan.                           │ │\n",
-       "│   │ │ MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed         │ │\n",
-       "│   │ │ Forces and their dependents relating to extensions of consumer credit. In general, the cost of consumer │ │\n",
-       "│   │ │ credit                                                                                                  │ │\n",
-       "│   │ │ to a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of 36 │ │\n",
-       "│   │ │ percent. This rate must include, as applicable to the credit transaction or account: the costs          │ │\n",
-       "│   │ │ associated with                                                                                         │ │\n",
-       "│   │ │ credit insurance premiums; fees for ancillary products sold in connection with the credit transaction;  │ │\n",
-       "│   │ │ any                                                                                                     │ │\n",
-       "│   │ │ application fee charged (other than certain application fees for specified credit transactions or       │ │\n",
-       "│   │ │ accounts); and                                                                                          │ │\n",
-       "│   │ │ any participation fee charged (other than certain participation fees for a credit card account). To     │ │\n",
-       "│   │ │ receive this                                                                                            │ │\n",
-       "│   │ │ information and a description of your payment obligation verbally, please call 1-800-235-9978.          │ │\n",
-       "│   │ │ TERMS & CONDITIONS                                                                                      │ │\n",
-       "│   │ │ Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC,  │ │\n",
-       "│   │ │ a                                                                                                       │ │\n",
-       "│   │ │ subsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:                │ │\n",
-       "│   │ │ 1. You authorize us to obtain credit bureau reports, employment, and income information about you that  │ │\n",
-       "│   │ │ we                                                                                                      │ │\n",
-       "│   │ │ will use when considering your application for credit. We may obtain and use information about your     │ │\n",
-       "│   │ │ accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit     │ │\n",
-       "│   │ │ bureaus and other entities. You also authorize us to obtain credit bureau reports and any other         │ │\n",
-       "│   │ │ information about you in connection with: 1) extensions of credit on your account; 2) the               │ │\n",
-       "│   │ │ administration,                                                                                         │ │\n",
-       "│   │ │ review or collection of your account; and 3) offering you enhanced or additional products and services. │ │\n",
-       "│   │ │ If                                                                                                      │ │\n",
-       "│   │ │ you ask, we will tell you the name and address of the credit bureau from which we obtained a report     │ │\n",
-       "│   │ │ about you.                                                                                              │ │\n",
-       "│   │ │ 2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You agree to the │ │\n",
-       "│   │ │ terms of this agreement by: using the account or any card, authorizing their use, or making any payment │ │\n",
-       "│   │ │ on the account.                                                                                         │ │\n",
-       "│   │ │ 3. By providing your mobile ph                                                                          │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "│   │ │ it into.                                                                                                │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ <output>                                                                                                │ │\n",
-       "│   │ │     <list name=\"fees\" description=\"What fees and charges are associated with my account?\">              │ │\n",
-       "│   │ │         <object>                                                                                        │ │\n",
-       "│   │ │             <string name=\"name\" format=\"guardrails/lowercase; guardrails/two_words\"/>                   │ │\n",
-       "│   │ │             <string name=\"explanation\" format=\"guardrails/one_line\"/>                                   │ │\n",
-       "│   │ │             <float name=\"value\" description=\"The fee amount in USD or as a percentage.\"/>               │ │\n",
-       "│   │ │         </object>                                                                                       │ │\n",
-       "│   │ │     </list>                                                                                             │ │\n",
-       "│   │ │     <list name=\"interest_rates\" description=\"What are the interest rates offered by the bank on         │ │\n",
-       "│   │ │ different kinds of accounts and products?\">                                                             │ │\n",
-       "│   │ │         <object>                                                                                        │ │\n",
-       "│   │ │             <string name=\"account_type\" format=\"guardrails/lowercase\"/>                                 │ │\n",
-       "│   │ │             <float name=\"rate\" description=\"The annual percentage rate (APR) for the account type.\"/>   │ │\n",
-       "│   │ │         </object>                                                                                       │ │\n",
-       "│   │ │     </list>                                                                                             │ │\n",
-       "│   │ │ </output>                                                                                               │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "│   │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "│   │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "│   │ │ requests for lists, objects and specific types. Be correct and concise.                                 │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "│   │ │ etc.]}`                                                                                                 │ │\n",
-       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "│   │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "│   │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "│   │ │ No message history.                                                                                     │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "│   │ │ {                                                                                                       │ │\n",
-       "│   │ │     \"fees\": [                                                                                           │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"annual membership\",                                                                │ │\n",
-       "│   │ │             \"explanation\": \"None\",                                                                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"my chase plan fee\",                                                                │ │\n",
-       "│   │ │             \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or    │ │\n",
-       "│   │ │ amount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that,        │ │\n",
-       "│   │ │ monthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a │ │\n",
-       "│   │ │ My Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and   │ │\n",
-       "│   │ │ will remain the same until the My Chase Plan is paid in full.\",                                         │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"transaction fees\",                                                                 │ │\n",
-       "│   │ │             \"explanation\": \"Balance Transfers: Intro fee of either $5 or 3% of the amount of each       │ │\n",
-       "│   │ │ transfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either │ │\n",
-       "│   │ │ $5 or 5% of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the   │ │\n",
-       "│   │ │ amount of each transaction, whichever is greater.\",                                                     │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"foreign transactions\",                                                             │ │\n",
-       "│   │ │             \"explanation\": \"3% of the amount of each transaction in U.S. dollars\",                      │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"name\": \"penalty fees\",                                                                     │ │\n",
-       "│   │ │             \"explanation\": \"Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to │ │\n",
-       "│   │ │ $40. Return Check: None\",                                                                               │ │\n",
-       "│   │ │             \"value\": 0                                                                                  │ │\n",
-       "│   │ │         }                                                                                               │ │\n",
-       "│   │ │     ],                                                                                                  │ │\n",
-       "│   │ │     \"interest_rates\": [                                                                                 │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"account_type\": \"purchase/my chase loan/balance transfer\",                                  │ │\n",
-       "│   │ │             \"rate\": 19.49                                                                               │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"account_type\": \"cash advance\",                                                             │ │\n",
-       "│   │ │             \"rate\": 29.49                                                                               │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             \"account_type\": \"penalty\",                                                                  │ │\n",
-       "│   │ │             \"rate\": 29.99                                                                               │ │\n",
-       "│   │ │         }                                                                                               │ │\n",
-       "│   │ │     ]                                                                                                   │ │\n",
-       "│   │ │ }                                                                                                       │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "│   │ │ {                                                                                                       │ │\n",
-       "│   │ │     'fees': [                                                                                           │ │\n",
-       "│   │ │         {'name': 'annual membership', 'explanation': 'None', 'value': 0.0},                             │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': FieldReAsk(                                                                         │ │\n",
-       "│   │ │                 incorrect_value='my chase plan fee',                                                    │ │\n",
-       "│   │ │                 fail_results=[                                                                          │ │\n",
-       "│   │ │                     FailResult(                                                                         │ │\n",
-       "│   │ │                         outcome='fail',                                                                 │ │\n",
-       "│   │ │                         metadata=None,                                                                  │ │\n",
-       "│   │ │                         error_message='Value must be exactly two words',                                │ │\n",
-       "│   │ │                         fix_value='my chase'                                                            │ │\n",
-       "│   │ │                     )                                                                                   │ │\n",
-       "│   │ │                 ],                                                                                      │ │\n",
-       "│   │ │                 path=['fees', 1, 'name']                                                                │ │\n",
-       "│   │ │             ),                                                                                          │ │\n",
-       "│   │ │             'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or    │ │\n",
-       "│   │ │ amount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that,        │ │\n",
-       "│   │ │ monthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a │ │\n",
-       "│   │ │ My Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and   │ │\n",
-       "│   │ │ will remain the same until the My Chase Plan is paid in full.',                                         │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': 'transaction fees',                                                                 │ │\n",
-       "│   │ │             'explanation': 'Balance Transfers: Intro fee of either $5 or 3% of the amount of each       │ │\n",
-       "│   │ │ transfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either │ │\n",
-       "│   │ │ $5 or 5% of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the   │ │\n",
-       "│   │ │ amount of each transaction, whichever is greater.',                                                     │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': 'foreign transactions',                                                             │ │\n",
-       "│   │ │             'explanation': '3% of the amount of each transaction in U.S. dollars',                      │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'name': 'penalty fees',                                                                     │ │\n",
-       "│   │ │             'explanation': 'Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to │ │\n",
-       "│   │ │ $40. Return Check: None',                                                                               │ │\n",
-       "│   │ │             'value': 0.0                                                                                │ │\n",
-       "│   │ │         }                                                                                               │ │\n",
-       "│   │ │     ],                                                                                                  │ │\n",
-       "│   │ │     'interest_rates': [                                                                                 │ │\n",
-       "│   │ │         {                                                                                               │ │\n",
-       "│   │ │             'account_type': 'purchase/my chase loan/balance transfer',                                  │ │\n",
-       "│   │ │             'rate': 19.49                                                                               │ │\n",
-       "│   │ │         },                                                                                              │ │\n",
-       "│   │ │         {'account_type': 'cash advance', 'rate': 29.49},                                                │ │\n",
-       "│   │ │         {'account_type': 'penalty', 'rate': 29.99}                                                      │ │\n",
-       "│   │ │     ]                                                                                                   │ │\n",
-       "│   │ │ }                                                                                                       │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
+       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ I was given the following JSON response, which had problems due to incorrect values.                    │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ {                                                                                                       │ │\n",
-       "    │ │   \"fees\": [                                                                                             │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"annual membership\",                                                                      │ │\n",
-       "    │ │       \"explanation\": \"None\",                                                                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": {                                                                                         │ │\n",
-       "    │ │         \"incorrect_value\": \"my chase plan fee\",                                                         │ │\n",
-       "    │ │         \"error_messages\": [                                                                             │ │\n",
-       "    │ │           \"Value must be exactly two words\"                                                             │ │\n",
-       "    │ │         ]                                                                                               │ │\n",
-       "    │ │       },                                                                                                │ │\n",
-       "    │ │       \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount   │ │\n",
-       "    │ │ selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee   │ │\n",
-       "    │ │ of 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase    │ │\n",
-       "    │ │ Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will       │ │\n",
-       "    │ │ remain the same until the My Chase Plan is paid in full.\",                                              │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"transaction fees\",                                                                       │ │\n",
-       "    │ │       \"explanation\": \"Balance Transfers: Intro fee of either $5 or 3% of the amount of each transfer,   │ │\n",
-       "    │ │ whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5%  │ │\n",
-       "    │ │ of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the amount of  │ │\n",
-       "    │ │ each transaction, whichever is greater.\",                                                               │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"foreign transactions\",                                                                   │ │\n",
-       "    │ │       \"explanation\": \"3% of the amount of each transaction in U.S. dollars\",                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"penalty fees\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to $40.  │ │\n",
-       "    │ │ Return Check: None\",                                                                                    │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
-       "    │ │     }                                                                                                   │ │\n",
-       "    │ │   ],                                                                                                    │ │\n",
-       "    │ │   \"interest_rates\": [                                                                                   │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"account_type\": \"purchase/my chase loan/balance transfer\",                                        │ │\n",
-       "    │ │       \"rate\": 19.49                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"account_type\": \"cash advance\",                                                                   │ │\n",
-       "    │ │       \"rate\": 29.49                                                                                     │ │\n",
-       "    │ │     },                                                                                                  │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"account_type\": \"penalty\",                                                                        │ │\n",
-       "    │ │       \"rate\": 29.99                                                                                     │ │\n",
-       "    │ │     }                                                                                                   │ │\n",
-       "    │ │   ]                                                                                                     │ │\n",
-       "    │ │ }                                                                                                       │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Help me correct the incorrect values based on the given error messages.                                 │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <list name=\"fees\" description=\"What fees and charges are associated with my account?\">              │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <string name=\"name\" format=\"guardrails/lowercase; guardrails/two_words\"/>                   │ │\n",
-       "    │ │             <string name=\"explanation\" format=\"guardrails/one_line\"/>                                   │ │\n",
-       "    │ │             <float name=\"value\" description=\"The fee amount in USD or as a percentage.\"/>               │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
-       "    │ │     <list name=\"interest_rates\" description=\"What are the interest rates offered by the bank on         │ │\n",
-       "    │ │ different kinds of accounts and products?\">                                                             │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <string name=\"account_type\" format=\"guardrails/lowercase\"/>                                 │ │\n",
-       "    │ │             <float name=\"rate\" description=\"The annual percentage rate (APR) for the account type.\"/>   │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given the following document, answer the following questions. If the answer doesn't exist in │ │ │\n",
+       "    │ │ │      │ the document, enter 'None'.                                                                  │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ 2/25/23, 7:59 PM about:blank                                                                 │ │ │\n",
+       "    │ │ │      │ about:blank 1/4                                                                              │ │ │\n",
+       "    │ │ │      │ PRICING INFORMATION                                                                          │ │ │\n",
+       "    │ │ │      │ INTEREST RATES AND INTEREST CHARGES                                                          │ │ │\n",
+       "    │ │ │      │ Purchase Annual                                                                              │ │ │\n",
+       "    │ │ │      │ Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.        │ │ │\n",
+       "    │ │ │      │ After that, 19.49%. This APR will vary with the market based on the Prime                    │ │ │\n",
+       "    │ │ │      │ Rate.                                                                                        │ │ │\n",
+       "    │ │ │      │ a                                                                                            │ │ │\n",
+       "    │ │ │      │ My Chase Loan                                                                                │ │ │\n",
+       "    │ │ │      │ SM APR 19.49%. This APR will vary with the market based on the Prime Rate.                   │ │ │\n",
+       "    │ │ │      │ a                                                                                            │ │ │\n",
+       "    │ │ │      │ Promotional offers with fixed APRs and varying durations may be available from               │ │ │\n",
+       "    │ │ │      │ time to time on some accounts.                                                               │ │ │\n",
+       "    │ │ │      │ Balance Transfer APR 0% Intro APR for the first 18 months that your Account is open.         │ │ │\n",
+       "    │ │ │      │ After that, 19.49%. This APR will vary with the market based on the Prime                    │ │ │\n",
+       "    │ │ │      │ Rate.                                                                                        │ │ │\n",
+       "    │ │ │      │ a                                                                                            │ │ │\n",
+       "    │ │ │      │ Cash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.         │ │ │\n",
+       "    │ │ │      │ b                                                                                            │ │ │\n",
+       "    │ │ │      │ Penalty APR and When                                                                         │ │ │\n",
+       "    │ │ │      │ It Applies                                                                                   │ │ │\n",
+       "    │ │ │      │ Up to 29.99%. This APR will vary with the market based on the Prime Rate.                    │ │ │\n",
+       "    │ │ │      │ c                                                                                            │ │ │\n",
+       "    │ │ │      │ We may apply the Penalty APR to your account if you:                                         │ │ │\n",
+       "    │ │ │      │ fail to make a Minimum Payment by the date and time that it is due; or                       │ │ │\n",
+       "    │ │ │      │ make a payment to us that is returned unpaid.                                                │ │ │\n",
+       "    │ │ │      │ How Long Will the Penalty APR Apply?: If we apply the Penalty APR for                        │ │ │\n",
+       "    │ │ │      │ either of these reasons, the Penalty APR could potentially remain in effect                  │ │ │\n",
+       "    │ │ │      │ indefinitely.                                                                                │ │ │\n",
+       "    │ │ │      │ How to Avoid Paying                                                                          │ │ │\n",
+       "    │ │ │      │ Interest on Purchases                                                                        │ │ │\n",
+       "    │ │ │      │ Your due date will be a minimum of 21 days after the close of each billing cycle.            │ │ │\n",
+       "    │ │ │      │ We will not charge you interest on new purchases if you pay your entire balance              │ │ │\n",
+       "    │ │ │      │ or Interest Saving Balance by the due date each month. We will begin charging                │ │ │\n",
+       "    │ │ │      │ interest on balance transfers and cash advances on the transaction date.                     │ │ │\n",
+       "    │ │ │      │ Minimum Interest                                                                             │ │ │\n",
+       "    │ │ │      │ Charge                                                                                       │ │ │\n",
+       "    │ │ │      │ None                                                                                         │ │ │\n",
+       "    │ │ │      │ Credit Card Tips from                                                                        │ │ │\n",
+       "    │ │ │      │ the Consumer Financial                                                                       │ │ │\n",
+       "    │ │ │      │ Protection Bureau                                                                            │ │ │\n",
+       "    │ │ │      │ To learn more about factors to consider when applying for or using a credit card,            │ │ │\n",
+       "    │ │ │      │ visit the website of the Consumer Financial Protection Bureau at                             │ │ │\n",
+       "    │ │ │      │ http://www.consumerfinance.gov/learnmore.                                                    │ │ │\n",
+       "    │ │ │      │ FEES                                                                                         │ │ │\n",
+       "    │ │ │      │ Annual Membership                                                                            │ │ │\n",
+       "    │ │ │      │ Fee                                                                                          │ │ │\n",
+       "    │ │ │      │ None                                                                                         │ │ │\n",
+       "    │ │ │      │ My Chase Plan                                                                                │ │ │\n",
+       "    │ │ │      │ SM Fee                                                                                       │ │ │\n",
+       "    │ │ │      │ (fixed finance charge)                                                                       │ │ │\n",
+       "    │ │ │      │ Monthly fee of 0% of the amount of each eligible purchase transaction or                     │ │ │\n",
+       "    │ │ │      │ amount selected to create a My Chase Plan while in the 0% Intro Purchase                     │ │ │\n",
+       "    │ │ │      │ APR period.                                                                                  │ │ │\n",
+       "    │ │ │      │ After that, monthly fee of 1.72% of the amount of each eligible purchase                     │ │ │\n",
+       "    │ │ │      │ transaction or amount selected to create a My Chase Plan. The My Chase Plan                  │ │ │\n",
+       "    │ │ │      │ Fee will be determined at the time each My Chase Plan is created and will                    │ │ │\n",
+       "    │ │ │      │ remain the same until the My Chase Plan is paid in full.                                     │ │ │\n",
+       "    │ │ │      │ d                                                                                            │ │ │\n",
+       "    │ │ │      │ Transaction Fees                                                                             │ │ │\n",
+       "    │ │ │      │ Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is  │ │ │\n",
+       "    │ │ │      │ greater,                                                                                     │ │ │\n",
+       "    │ │ │      │ on transfers made within 60 days of account opening. After that: Either $5 or 5%             │ │ │\n",
+       "    │ │ │      │ of the amount of each transfer, whichever is greater.                                        │ │ │\n",
+       "    │ │ │      │ Cash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.      │ │ │\n",
+       "    │ │ │      │ 2/25/23, 7:59 PM about:blank                                                                 │ │ │\n",
+       "    │ │ │      │ about:blank 2/4                                                                              │ │ │\n",
+       "    │ │ │      │ Foreign Transactions 3% of the amount of each transaction in U.S. dollars.                   │ │ │\n",
+       "    │ │ │      │ Penalty Fees                                                                                 │ │ │\n",
+       "    │ │ │      │ Late Payment Up to $40.                                                                      │ │ │\n",
+       "    │ │ │      │ Over-the-Credit-Limit None                                                                   │ │ │\n",
+       "    │ │ │      │ Return Payment Up to $40.                                                                    │ │ │\n",
+       "    │ │ │      │ Return Check None                                                                            │ │ │\n",
+       "    │ │ │      │ Note: This account may not be eligible for balance transfers.                                │ │ │\n",
+       "    │ │ │      │ Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60   │ │ │\n",
+       "    │ │ │      │ days late, and                                                                               │ │ │\n",
+       "    │ │ │      │ apply the Penalty APR.                                                                       │ │ │\n",
+       "    │ │ │      │ How We Will Calculate Your Balance: We use the daily balance method (including new           │ │ │\n",
+       "    │ │ │      │ transactions).                                                                               │ │ │\n",
+       "    │ │ │      │ Prime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.                  │ │ │\n",
+       "    │ │ │      │ aWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer    │ │ │\n",
+       "    │ │ │      │ APR.                                                                                         │ │ │\n",
+       "    │ │ │      │ Maximum APR 29.99%.                                                                          │ │ │\n",
+       "    │ │ │      │ bWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.      │ │ │\n",
+       "    │ │ │      │ cWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.     │ │ │\n",
+       "    │ │ │      │ dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and │ │ │\n",
+       "    │ │ │      │ is based on                                                                                  │ │ │\n",
+       "    │ │ │      │ the amount of each purchase transaction or amount selected to create the plan, the number of │ │ │\n",
+       "    │ │ │      │ billing periods                                                                              │ │ │\n",
+       "    │ │ │      │ you choose to pay the balance in full, and other factors. The monthly and aggregate dollar   │ │ │\n",
+       "    │ │ │      │ amount of your My                                                                            │ │ │\n",
+       "    │ │ │      │ Chase Plan Fee will be disclosed during the activation of each My Chase Plan.                │ │ │\n",
+       "    │ │ │      │ MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the    │ │ │\n",
+       "    │ │ │      │ Armed                                                                                        │ │ │\n",
+       "    │ │ │      │ Forces and their dependents relating to extensions of consumer credit. In general, the cost  │ │ │\n",
+       "    │ │ │      │ of consumer credit                                                                           │ │ │\n",
+       "    │ │ │      │ to a member of the Armed Forces and his or her dependent may not exceed an annual percentage │ │ │\n",
+       "    │ │ │      │ rate of 36                                                                                   │ │ │\n",
+       "    │ │ │      │ percent. This rate must include, as applicable to the credit transaction or account: the     │ │ │\n",
+       "    │ │ │      │ costs associated with                                                                        │ │ │\n",
+       "    │ │ │      │ credit insurance premiums; fees for ancillary products sold in connection with the credit    │ │ │\n",
+       "    │ │ │      │ transaction; any                                                                             │ │ │\n",
+       "    │ │ │      │ application fee charged (other than certain application fees for specified credit            │ │ │\n",
+       "    │ │ │      │ transactions or accounts); and                                                               │ │ │\n",
+       "    │ │ │      │ any participation fee charged (other than certain participation fees for a credit card       │ │ │\n",
+       "    │ │ │      │ account). To receive this                                                                    │ │ │\n",
+       "    │ │ │      │ information and a description of your payment obligation verbally, please call               │ │ │\n",
+       "    │ │ │      │ 1-800-235-9978.                                                                              │ │ │\n",
+       "    │ │ │      │ TERMS & CONDITIONS                                                                           │ │ │\n",
+       "    │ │ │      │ Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A.,    │ │ │\n",
+       "    │ │ │      │ Member FDIC, a                                                                               │ │ │\n",
+       "    │ │ │      │ subsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:     │ │ │\n",
+       "    │ │ │      │ 1. You authorize us to obtain credit bureau reports, employment, and income information      │ │ │\n",
+       "    │ │ │      │ about you that we                                                                            │ │ │\n",
+       "    │ │ │      │ will use when considering your application for credit. We may obtain and use information     │ │ │\n",
+       "    │ │ │      │ about your                                                                                   │ │ │\n",
+       "    │ │ │      │ accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from │ │ │\n",
+       "    │ │ │      │ credit                                                                                       │ │ │\n",
+       "    │ │ │      │ bureaus and other entities. You also authorize us to obtain credit bureau reports and any    │ │ │\n",
+       "    │ │ │      │ other                                                                                        │ │ │\n",
+       "    │ │ │      │ information about you in connection with: 1) extensions of credit on your account; 2) the    │ │ │\n",
+       "    │ │ │      │ administration,                                                                              │ │ │\n",
+       "    │ │ │      │ review or collection of your account; and 3) offering you enhanced or additional products    │ │ │\n",
+       "    │ │ │      │ and services. If                                                                             │ │ │\n",
+       "    │ │ │      │ you ask, we will tell you the name and address of the credit bureau from which we obtained a │ │ │\n",
+       "    │ │ │      │ report                                                                                       │ │ │\n",
+       "    │ │ │      │ about you.                                                                                   │ │ │\n",
+       "    │ │ │      │ 2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You   │ │ │\n",
+       "    │ │ │      │ agree to the                                                                                 │ │ │\n",
+       "    │ │ │      │ terms of this agreement by: using the account or any card, authorizing their use, or making  │ │ │\n",
+       "    │ │ │      │ any payment                                                                                  │ │ │\n",
+       "    │ │ │      │ on the account.                                                                              │ │ │\n",
+       "    │ │ │      │ 3. By providing your mobile ph                                                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <list description=\"What fees and charges are associated with my account?\" name=\"fees\"      │ │ │\n",
+       "    │ │ │      │ required=\"true\">                                                                             │ │ │\n",
+       "    │ │ │      │     <object required=\"true\">                                                                 │ │ │\n",
+       "    │ │ │      │       <string format=\"guardrails/lowercase; guardrails/two_words\" name=\"name\"                │ │ │\n",
+       "    │ │ │      │ required=\"true\"></string>                                                                    │ │ │\n",
+       "    │ │ │      │       <string format=\"guardrails/one_line\" name=\"explanation\" required=\"true\"></string>      │ │ │\n",
+       "    │ │ │      │       <float description=\"The fee amount in USD or as a percentage.\" name=\"value\"            │ │ │\n",
+       "    │ │ │      │ required=\"true\"></float>                                                                     │ │ │\n",
+       "    │ │ │      │     </object>                                                                                │ │ │\n",
+       "    │ │ │      │   </list>                                                                                    │ │ │\n",
+       "    │ │ │      │   <list description=\"What are the interest rates offered by the bank on different kinds of   │ │ │\n",
+       "    │ │ │      │ accounts and products?\" name=\"interest_rates\" required=\"true\">                               │ │ │\n",
+       "    │ │ │      │     <object required=\"true\">                                                                 │ │ │\n",
+       "    │ │ │      │       <string format=\"guardrails/lowercase\" name=\"account_type\" required=\"true\"></string>    │ │ │\n",
+       "    │ │ │      │       <float description=\"The annual percentage rate (APR) for the account type.\"            │ │ │\n",
+       "    │ │ │      │ name=\"rate\" required=\"true\"></float>                                                         │ │ │\n",
+       "    │ │ │      │     </object>                                                                                │ │ │\n",
+       "    │ │ │      │   </list>                                                                                    │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise.                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ ```json                                                                                                 │ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │   \"fees\": [                                                                                             │ │\n",
        "    │ │     {                                                                                                   │ │\n",
@@ -1056,37 +1052,52 @@
        "    │ │       \"value\": 0.0                                                                                      │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"my chase plan fee\",                                                                      │ │\n",
+       "    │ │       \"name\": \"my chase\",                                                                               │ │\n",
        "    │ │       \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount   │ │\n",
        "    │ │ selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee   │ │\n",
        "    │ │ of 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase    │ │\n",
-       "    │ │ Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will       │ │\n",
-       "    │ │ remain the same until the My Chase Plan is paid in full.\",                                              │ │\n",
+       "    │ │ Plan.\",                                                                                                 │ │\n",
        "    │ │       \"value\": 0.0                                                                                      │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"transaction fees\",                                                                       │ │\n",
-       "    │ │       \"explanation\": \"Balance Transfers: Intro fee of either $5 or 3% of the amount of each transfer,   │ │\n",
-       "    │ │ whichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5%  │ │\n",
-       "    │ │ of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the amount of  │ │\n",
-       "    │ │ each transaction, whichever is greater.\",                                                               │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"name\": \"balance transfers\",                                                                      │ │\n",
+       "    │ │       \"explanation\": \"Intro fee of either $5 or 3% of the amount of each transfer, whichever is         │ │\n",
+       "    │ │ greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount │ │\n",
+       "    │ │ of each transfer, whichever is greater.\",                                                               │ │\n",
+       "    │ │       \"value\": 5.0                                                                                      │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"name\": \"cash advances\",                                                                          │ │\n",
+       "    │ │       \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",       │ │\n",
+       "    │ │       \"value\": 10.0                                                                                     │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
        "    │ │       \"name\": \"foreign transactions\",                                                                   │ │\n",
-       "    │ │       \"explanation\": \"3% of the amount of each transaction in U.S. dollars\",                            │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",                           │ │\n",
+       "    │ │       \"value\": 3.0                                                                                      │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"name\": \"penalty fees\",                                                                           │ │\n",
-       "    │ │       \"explanation\": \"Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to $40.  │ │\n",
-       "    │ │ Return Check: None\",                                                                                    │ │\n",
-       "    │ │       \"value\": 0.0                                                                                      │ │\n",
+       "    │ │       \"name\": \"late payment\",                                                                           │ │\n",
+       "    │ │       \"explanation\": \"Up to $40.\",                                                                      │ │\n",
+       "    │ │       \"value\": 40.0                                                                                     │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"name\": \"return payment\",                                                                         │ │\n",
+       "    │ │       \"explanation\": \"Up to $40.\",                                                                      │ │\n",
+       "    │ │       \"value\": 40.0                                                                                     │ │\n",
        "    │ │     }                                                                                                   │ │\n",
        "    │ │   ],                                                                                                    │ │\n",
        "    │ │   \"interest_rates\": [                                                                                   │ │\n",
        "    │ │     {                                                                                                   │ │\n",
-       "    │ │       \"account_type\": \"purchase/my chase loan/balance transfer\",                                        │ │\n",
+       "    │ │       \"account_type\": \"purchase\",                                                                       │ │\n",
+       "    │ │       \"rate\": 19.49                                                                                     │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"account_type\": \"my chase loan\",                                                                  │ │\n",
+       "    │ │       \"rate\": 19.49                                                                                     │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"account_type\": \"balance transfer\",                                                               │ │\n",
        "    │ │       \"rate\": 19.49                                                                                     │ │\n",
        "    │ │     },                                                                                                  │ │\n",
        "    │ │     {                                                                                                   │ │\n",
@@ -1099,6 +1110,7 @@
        "    │ │     }                                                                                                   │ │\n",
        "    │ │   ]                                                                                                     │ │\n",
        "    │ │ }                                                                                                       │ │\n",
+       "    │ │ ```                                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
@@ -1109,35 +1121,33 @@
        "    │ │             'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or    │ │\n",
        "    │ │ amount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that,        │ │\n",
        "    │ │ monthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a │ │\n",
-       "    │ │ My Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and   │ │\n",
-       "    │ │ will remain the same until the My Chase Plan is paid in full.',                                         │ │\n",
+       "    │ │ My Chase Plan.',                                                                                        │ │\n",
        "    │ │             'value': 0.0                                                                                │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             'name': 'transaction fees',                                                                 │ │\n",
-       "    │ │             'explanation': 'Balance Transfers: Intro fee of either $5 or 3% of the amount of each       │ │\n",
-       "    │ │ transfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either │ │\n",
-       "    │ │ $5 or 5% of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the   │ │\n",
-       "    │ │ amount of each transaction, whichever is greater.',                                                     │ │\n",
-       "    │ │             'value': 0.0                                                                                │ │\n",
+       "    │ │             'name': 'balance transfers',                                                                │ │\n",
+       "    │ │             'explanation': 'Intro fee of either $5 or 3% of the amount of each transfer, whichever is   │ │\n",
+       "    │ │ greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount │ │\n",
+       "    │ │ of each transfer, whichever is greater.',                                                               │ │\n",
+       "    │ │             'value': 5.0                                                                                │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             'name': 'foreign transactions',                                                             │ │\n",
-       "    │ │             'explanation': '3% of the amount of each transaction in U.S. dollars',                      │ │\n",
-       "    │ │             'value': 0.0                                                                                │ │\n",
+       "    │ │             'name': 'cash advances',                                                                    │ │\n",
+       "    │ │             'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.', │ │\n",
+       "    │ │             'value': 10.0                                                                               │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             'name': 'penalty fees',                                                                     │ │\n",
-       "    │ │             'explanation': 'Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to │ │\n",
-       "    │ │ $40. Return Check: None',                                                                               │ │\n",
-       "    │ │             'value': 0.0                                                                                │ │\n",
-       "    │ │         }                                                                                               │ │\n",
+       "    │ │             'name': 'foreign transactions',                                                             │ │\n",
+       "    │ │             'explanation': '3% of the amount of each transaction in U.S. dollars.',                     │ │\n",
+       "    │ │             'value': 3.0                                                                                │ │\n",
+       "    │ │         },                                                                                              │ │\n",
+       "    │ │         {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},                           │ │\n",
+       "    │ │         {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0}                          │ │\n",
        "    │ │     ],                                                                                                  │ │\n",
        "    │ │     'interest_rates': [                                                                                 │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             'account_type': 'purchase/my chase loan/balance transfer',                                  │ │\n",
-       "    │ │             'rate': 19.49                                                                               │ │\n",
-       "    │ │         },                                                                                              │ │\n",
+       "    │ │         {'account_type': 'purchase', 'rate': 19.49},                                                    │ │\n",
+       "    │ │         {'account_type': 'my chase loan', 'rate': 19.49},                                               │ │\n",
+       "    │ │         {'account_type': 'balance transfer', 'rate': 19.49},                                            │ │\n",
        "    │ │         {'account_type': 'cash advance', 'rate': 29.49},                                                │ │\n",
        "    │ │         {'account_type': 'penalty', 'rate': 29.99}                                                      │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
@@ -1148,386 +1158,197 @@
       ],
       "text/plain": [
        "Logs\n",
-       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "│   │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven the following document, answer the following questions. If the answer doesn't exist in the \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdocument, enter 'None'.\u001b[0m\u001b[48;2;240;248;255m                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m2/25/23, 7:59 PM about:blank\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabout:blank 1/4\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPRICING INFORMATION\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mINTEREST RATES AND INTEREST CHARGES\u001b[0m\u001b[48;2;240;248;255m                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPurchase Annual\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPercentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.\u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAfter that, 19.49%. This APR will vary with the market based on the Prime\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRate.\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMy Chase Loan\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSM APR 19.49%. This APR will vary with the market based on the Prime Rate.\u001b[0m\u001b[48;2;240;248;255m                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPromotional offers with fixed APRs and varying durations may be available from\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mtime to time on some accounts.\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mBalance Transfer APR 0% Intro APR for the first 18 months that your Account is open.\u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAfter that, 19.49%. This APR will vary with the market based on the Prime\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRate.\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.\u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mb\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPenalty APR and When\u001b[0m\u001b[48;2;240;248;255m                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIt Applies\u001b[0m\u001b[48;2;240;248;255m                                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mUp to 29.99%. This APR will vary with the market based on the Prime Rate.\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mc\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWe may apply the Penalty APR to your account if you:\u001b[0m\u001b[48;2;240;248;255m                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mfail to make a Minimum Payment by the date and time that it is due; or\u001b[0m\u001b[48;2;240;248;255m                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mmake a payment to us that is returned unpaid.\u001b[0m\u001b[48;2;240;248;255m                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow Long Will the Penalty APR Apply?: If we apply the Penalty APR for\u001b[0m\u001b[48;2;240;248;255m                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255meither of these reasons, the Penalty APR could potentially remain in effect\u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mindefinitely.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow to Avoid Paying\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mInterest on Purchases\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYour due date will be a minimum of 21 days after the close of each billing cycle.\u001b[0m\u001b[48;2;240;248;255m                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWe will not charge you interest on new purchases if you pay your entire balance\u001b[0m\u001b[48;2;240;248;255m                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mor Interest Saving Balance by the due date each month. We will begin charging\u001b[0m\u001b[48;2;240;248;255m                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255minterest on balance transfers and cash advances on the transaction date.\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMinimum Interest\u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCharge\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNone\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCredit Card Tips from\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthe Consumer Financial\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mProtection Bureau\u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTo learn more about factors to consider when applying for or using a credit card,\u001b[0m\u001b[48;2;240;248;255m                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mvisit the website of the Consumer Financial Protection Bureau at\u001b[0m\u001b[48;2;240;248;255m                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mhttp://www.consumerfinance.gov/learnmore.\u001b[0m\u001b[48;2;240;248;255m                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFEES\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAnnual Membership\u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFee\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNone\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMy Chase Plan\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSM Fee\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m(fixed finance charge)\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMonthly fee of 0% of the amount of each eligible purchase transaction or\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mamount selected to create a My Chase Plan while in the 0% Intro Purchase\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAPR period.\u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAfter that, monthly fee of 1.72% of the amount of each eligible purchase\u001b[0m\u001b[48;2;240;248;255m                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mtransaction or amount selected to create a My Chase Plan. The My Chase Plan\u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFee will be determined at the time each My Chase Plan is created and will\u001b[0m\u001b[48;2;240;248;255m                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mremain the same until the My Chase Plan is paid in full.\u001b[0m\u001b[48;2;240;248;255m                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255md\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTransaction Fees\u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mBalance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater,\u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mon transfers made within 60 days of account opening. After that: Either $5 or 5%\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mof the amount of each transfer, whichever is greater.\u001b[0m\u001b[48;2;240;248;255m                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mCash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.\u001b[0m\u001b[48;2;240;248;255m                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m2/25/23, 7:59 PM about:blank\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabout:blank 2/4\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mForeign Transactions 3% of the amount of each transaction in U.S. dollars.\u001b[0m\u001b[48;2;240;248;255m                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPenalty Fees\u001b[0m\u001b[48;2;240;248;255m                                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mLate Payment Up to $40.\u001b[0m\u001b[48;2;240;248;255m                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mOver-the-Credit-Limit None\u001b[0m\u001b[48;2;240;248;255m                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mReturn Payment Up to $40.\u001b[0m\u001b[48;2;240;248;255m                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mReturn Check None\u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNote: This account may not be eligible for balance transfers.\u001b[0m\u001b[48;2;240;248;255m                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mLoss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60 days late, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mand\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mapply the Penalty APR.\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow We Will Calculate Your Balance: We use the daily balance method (including new transactions).\u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPrime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.\u001b[0m\u001b[48;2;240;248;255m                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255maWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.\u001b[0m\u001b[48;2;240;248;255m         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMaximum APR 29.99%.\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.\u001b[0m\u001b[48;2;240;248;255m                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mcWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.\u001b[0m\u001b[48;2;240;248;255m               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mon\u001b[0m\u001b[48;2;240;248;255m                                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthe amount of each purchase transaction or amount selected to create the plan, the number of billing \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mperiods\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255myou choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255myour My\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mChase Plan Fee will be disclosed during the activation of each My Chase Plan.\u001b[0m\u001b[48;2;240;248;255m                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mMILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed\u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mForces and their dependents relating to extensions of consumer credit. In general, the cost of consumer\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mcredit\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mto a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of 36\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mpercent. This rate must include, as applicable to the credit transaction or account: the costs \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255massociated with\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mcredit insurance premiums; fees for ancillary products sold in connection with the credit transaction; \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255many\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mapplication fee charged (other than certain application fees for specified credit transactions or \u001b[0m\u001b[48;2;240;248;255m     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255maccounts); and\u001b[0m\u001b[48;2;240;248;255m                                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255many participation fee charged (other than certain participation fees for a credit card account). To \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mreceive this\u001b[0m\u001b[48;2;240;248;255m                                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255minformation and a description of your payment obligation verbally, please call 1-800-235-9978.\u001b[0m\u001b[48;2;240;248;255m         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTERMS & CONDITIONS\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAuthorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255ma\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255msubsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:\u001b[0m\u001b[48;2;240;248;255m               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m1. You authorize us to obtain credit bureau reports, employment, and income information about you that \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwe\u001b[0m\u001b[48;2;240;248;255m                                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwill use when considering your application for credit. We may obtain and use information about your\u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255maccounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit\u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbureaus and other entities. You also authorize us to obtain credit bureau reports and any other\u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255minformation about you in connection with: 1) extensions of credit on your account; 2) the \u001b[0m\u001b[48;2;240;248;255m             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255madministration,\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mreview or collection of your account; and 3) offering you enhanced or additional products and services.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIf\u001b[0m\u001b[48;2;240;248;255m                                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255myou ask, we will tell you the name and address of the credit bureau from which we obtained a report\u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabout you.\u001b[0m\u001b[48;2;240;248;255m                                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You agree to the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mterms of this agreement by: using the account or any card, authorizing their use, or making any payment\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mon the account.\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m3. By providing your mobile ph\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise.\u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "│   │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "│   │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"fees\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"annual membership\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"None\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"my chase plan fee\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mamount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, \u001b[0m\u001b[48;2;245;245;220m      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mmonthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mMy Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mwill remain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;245;245;220m                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Balance Transfers: Intro fee of either $5 or 3% of the amount of each \u001b[0m\u001b[48;2;245;245;220m     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mtransfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m$5 or 5% of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mamount of each transaction, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"foreign transactions\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"3% of the amount of each transaction in U.S. dollars\",\u001b[0m\u001b[48;2;245;245;220m                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"explanation\": \"Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m$40. Return Check: None\",\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"value\": 0\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"interest_rates\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"account_type\": \"purchase/my chase loan/balance transfer\",\u001b[0m\u001b[48;2;245;245;220m                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"rate\": 19.49\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"account_type\": \"cash advance\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"rate\": 29.49\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"account_type\": \"penalty\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"rate\": 29.99\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'fees': [\u001b[0m\u001b[48;2;240;255;240m                                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'annual membership', 'explanation': 'None', 'value': 0.0},\u001b[0m\u001b[48;2;240;255;240m                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': FieldReAsk(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                incorrect_value='my chase plan fee',\u001b[0m\u001b[48;2;240;255;240m                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                fail_results=[\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    FailResult(\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        outcome='fail',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        error_message='Value must be exactly two words',\u001b[0m\u001b[48;2;240;255;240m                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                        fix_value='my chase'\u001b[0m\u001b[48;2;240;255;240m                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                    )\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                ],\u001b[0m\u001b[48;2;240;255;240m                                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m                path=['fees', 1, 'name']\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            ),\u001b[0m\u001b[48;2;240;255;240m                                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mamount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, \u001b[0m\u001b[48;2;240;255;240m      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mmonthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mMy Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mwill remain the same until the My Chase Plan is paid in full.',\u001b[0m\u001b[48;2;240;255;240m                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'transaction fees',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Balance Transfers: Intro fee of either $5 or 3% of the amount of each \u001b[0m\u001b[48;2;240;255;240m     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$5 or 5% of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mamount of each transaction, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'foreign transactions',\u001b[0m\u001b[48;2;240;255;240m                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': '3% of the amount of each transaction in U.S. dollars',\u001b[0m\u001b[48;2;240;255;240m                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'penalty fees',\u001b[0m\u001b[48;2;240;255;240m                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$40. Return Check: None',\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        }\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ],\u001b[0m\u001b[48;2;240;255;240m                                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'interest_rates': [\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'account_type': 'purchase/my chase loan/balance transfer',\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'rate': 19.49\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'cash advance', 'rate': 29.49},\u001b[0m\u001b[48;2;240;255;240m                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'penalty', 'rate': 29.99}\u001b[0m\u001b[48;2;240;255;240m                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "│   │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
+       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mI was given the following JSON response, which had problems due to incorrect values.\u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \"fees\": [\u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"annual membership\",\u001b[0m\u001b[48;2;240;248;255m                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"None\",\u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"incorrect_value\": \"my chase plan fee\",\u001b[0m\u001b[48;2;240;248;255m                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \"error_messages\": [\u001b[0m\u001b[48;2;240;248;255m                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m          \"Value must be exactly two words\"\u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        ]\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      },\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mselected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mof 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPlan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will \u001b[0m\u001b[48;2;240;248;255m     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mremain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;240;248;255m                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;240;248;255m                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Balance Transfers: Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mof the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the amount of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255meach transaction, whichever is greater.\",\u001b[0m\u001b[48;2;240;248;255m                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"foreign transactions\",\u001b[0m\u001b[48;2;240;248;255m                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"3% of the amount of each transaction in U.S. dollars\",\u001b[0m\u001b[48;2;240;248;255m                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;240;248;255m                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"explanation\": \"Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to $40. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mReturn Check: None\",\u001b[0m\u001b[48;2;240;248;255m                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"value\": 0.0\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    }\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  ],\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \"interest_rates\": [\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"account_type\": \"purchase/my chase loan/balance transfer\",\u001b[0m\u001b[48;2;240;248;255m                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"rate\": 19.49\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"account_type\": \"cash advance\",\u001b[0m\u001b[48;2;240;248;255m                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"rate\": 29.49\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    },\u001b[0m\u001b[48;2;240;248;255m                                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    {\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"account_type\": \"penalty\",\u001b[0m\u001b[48;2;240;248;255m                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"rate\": 29.99\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    }\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  ]\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHelp me correct the incorrect values based on the given error messages.\u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven the following document, answer the following questions. If the answer doesn't exist in\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe document, enter 'None'.                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m2/25/23, 7:59 PM about:blank                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout:blank 1/4                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPRICING INFORMATION                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mINTEREST RATES AND INTEREST CHARGES                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPurchase Annual                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPercentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAfter that, 19.49%. This APR will vary with the market based on the Prime                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mRate.                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMy Chase Loan                                                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSM APR 19.49%. This APR will vary with the market based on the Prime Rate.                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPromotional offers with fixed APRs and varying durations may be available from              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtime to time on some accounts.                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mBalance Transfer APR 0% Intro APR for the first 18 months that your Account is open.        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAfter that, 19.49%. This APR will vary with the market based on the Prime                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mRate.                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mb                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPenalty APR and When                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mIt Applies                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mUp to 29.99%. This APR will vary with the market based on the Prime Rate.                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mc                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mWe may apply the Penalty APR to your account if you:                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mfail to make a Minimum Payment by the date and time that it is due; or                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmake a payment to us that is returned unpaid.                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow Long Will the Penalty APR Apply?: If we apply the Penalty APR for                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235meither of these reasons, the Penalty APR could potentially remain in effect                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mindefinitely.                                                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow to Avoid Paying                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mInterest on Purchases                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mYour due date will be a minimum of 21 days after the close of each billing cycle.           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mWe will not charge you interest on new purchases if you pay your entire balance             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mor Interest Saving Balance by the due date each month. We will begin charging               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235minterest on balance transfers and cash advances on the transaction date.                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMinimum Interest                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCharge                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNone                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCredit Card Tips from                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe Consumer Financial                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mProtection Bureau                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTo learn more about factors to consider when applying for or using a credit card,           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mvisit the website of the Consumer Financial Protection Bureau at                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhttp://www.consumerfinance.gov/learnmore.                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mFEES                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAnnual Membership                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mFee                                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNone                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMy Chase Plan                                                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSM Fee                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m(fixed finance charge)                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMonthly fee of 0% of the amount of each eligible purchase transaction or                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mamount selected to create a My Chase Plan while in the 0% Intro Purchase                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAPR period.                                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAfter that, monthly fee of 1.72% of the amount of each eligible purchase                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransaction or amount selected to create a My Chase Plan. The My Chase Plan                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mFee will be determined at the time each My Chase Plan is created and will                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mremain the same until the My Chase Plan is paid in full.                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235md                                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTransaction Fees                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mBalance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mgreater,                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mon transfers made within 60 days of account opening. After that: Either $5 or 5%            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mof the amount of each transfer, whichever is greater.                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mCash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m2/25/23, 7:59 PM about:blank                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout:blank 2/4                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mForeign Transactions 3% of the amount of each transaction in U.S. dollars.                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPenalty Fees                                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mLate Payment Up to $40.                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mOver-the-Credit-Limit None                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mReturn Payment Up to $40.                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mReturn Check None                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNote: This account may not be eligible for balance transfers.                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mLoss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdays late, and                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mapply the Penalty APR.                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow We Will Calculate Your Balance: We use the daily balance method (including new          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransactions).                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mPrime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235maWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAPR.                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMaximum APR 29.99%.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mis based on                                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe amount of each purchase transaction or amount selected to create the plan, the number of\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbilling periods                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myou choose to pay the balance in full, and other factors. The monthly and aggregate dollar  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mamount of your My                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mChase Plan Fee will be disclosed during the activation of each My Chase Plan.               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mArmed                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mForces and their dependents relating to extensions of consumer credit. In general, the cost \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mof consumer credit                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto a member of the Armed Forces and his or her dependent may not exceed an annual percentage\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mrate of 36                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mpercent. This rate must include, as applicable to the credit transaction or account: the    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcosts associated with                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcredit insurance premiums; fees for ancillary products sold in connection with the credit   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransaction; any                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mapplication fee charged (other than certain application fees for specified credit           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mtransactions or accounts); and                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many participation fee charged (other than certain participation fees for a credit card      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235maccount). To receive this                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235minformation and a description of your payment obligation verbally, please call              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1-800-235-9978.                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTERMS & CONDITIONS                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mAuthorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A.,   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mMember FDIC, a                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msubsidiary of JPMorgan Chase & Co. (\"Chase\", \"we\", or \"us\"), you agree to the following:    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1. You authorize us to obtain credit bureau reports, employment, and income information     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout you that we                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwill use when considering your application for credit. We may obtain and use information    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout your                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235maccounts with us and others such as Checking, Deposit, Investment, and Utility accounts from\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcredit                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbureaus and other entities. You also authorize us to obtain credit bureau reports and any   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mother                                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235minformation about you in connection with: 1) extensions of credit on your account; 2) the   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235madministration,                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mreview or collection of your account; and 3) offering you enhanced or additional products   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand services. If                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myou ask, we will tell you the name and address of the credit bureau from which we obtained a\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mreport                                                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout you.                                                                                  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You  \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235magree to the                                                                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mterms of this agreement by: using the account or any card, authorizing their use, or making \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many payment                                                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mon the account.                                                                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m3. By providing your mobile ph                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise.                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"fees\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
@@ -1536,37 +1357,52 @@
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"my chase plan fee\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"my chase\",\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Monthly fee of 0% of the amount of each eligible purchase transaction or amount \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mselected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, monthly fee \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof 1.72% of the amount of each eligible purchase transaction or amount selected to create a My Chase \u001b[0m\u001b[48;2;245;245;220m  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPlan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and will \u001b[0m\u001b[48;2;245;245;220m     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mremain the same until the My Chase Plan is paid in full.\",\u001b[0m\u001b[48;2;245;245;220m                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPlan.\",\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"transaction fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Balance Transfers: Intro fee of either $5 or 3% of the amount of each transfer, \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mwhichever is greater, on transfers made within 60 days of account opening. After that: Either $5 or 5% \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the amount of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220meach transaction, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"balance transfers\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Intro fee of either $5 or 3% of the amount of each transfer, whichever is \u001b[0m\u001b[48;2;245;245;220m       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgreater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof each transfer, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 5.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"cash advances\",\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Either $10 or 5% of the amount of each transaction, whichever is greater.\",\u001b[0m\u001b[48;2;245;245;220m      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 10.0\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"foreign transactions\",\u001b[0m\u001b[48;2;245;245;220m                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"3% of the amount of each transaction in U.S. dollars\",\u001b[0m\u001b[48;2;245;245;220m                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"3% of the amount of each transaction in U.S. dollars.\",\u001b[0m\u001b[48;2;245;245;220m                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 3.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"penalty fees\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to $40. \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mReturn Check: None\",\u001b[0m\u001b[48;2;245;245;220m                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 0.0\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"late payment\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 40.0\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"return payment\",\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"explanation\": \"Up to $40.\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"value\": 40.0\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"interest_rates\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"purchase/my chase loan/balance transfer\",\u001b[0m\u001b[48;2;245;245;220m                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"purchase\",\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 19.49\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"my chase loan\",\u001b[0m\u001b[48;2;245;245;220m                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 19.49\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"account_type\": \"balance transfer\",\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"rate\": 19.49\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
@@ -1579,6 +1415,7 @@
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1589,35 +1426,33 @@
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Monthly fee of 0% of the amount of each eligible purchase transaction or \u001b[0m\u001b[48;2;240;255;240m  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mamount selected to create a My Chase Plan while in the 0% Intro Purchase APR period. After that, \u001b[0m\u001b[48;2;240;255;240m      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mmonthly fee of 1.72% of the amount of each eligible purchase transaction or amount selected to create a\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mMy Chase Plan. The My Chase Plan Fee will be determined at the time each My Chase Plan is created and \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mwill remain the same until the My Chase Plan is paid in full.',\u001b[0m\u001b[48;2;240;255;240m                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mMy Chase Plan.',\u001b[0m\u001b[48;2;240;255;240m                                                                                       \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'transaction fees',\u001b[0m\u001b[48;2;240;255;240m                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Balance Transfers: Intro fee of either $5 or 3% of the amount of each \u001b[0m\u001b[48;2;240;255;240m     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtransfer, whichever is greater, on transfers made within 60 days of account opening. After that: Either\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$5 or 5% of the amount of each transfer, whichever is greater. Cash Advances: Either $10 or 5% of the \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mamount of each transaction, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'balance transfers',\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Intro fee of either $5 or 3% of the amount of each transfer, whichever is \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mgreater, on transfers made within 60 days of account opening. After that: Either $5 or 5% of the amount\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mof each transfer, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 5.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'foreign transactions',\u001b[0m\u001b[48;2;240;255;240m                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': '3% of the amount of each transaction in U.S. dollars',\u001b[0m\u001b[48;2;240;255;240m                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'cash advances',\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Either $10 or 5% of the amount of each transaction, whichever is greater.',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 10.0\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'penalty fees',\u001b[0m\u001b[48;2;240;255;240m                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': 'Late Payment: Up to $40. Over-the-Credit-Limit: None. Return Payment: Up to\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m$40. Return Check: None',\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 0.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        }\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'foreign transactions',\u001b[0m\u001b[48;2;240;255;240m                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'explanation': '3% of the amount of each transaction in U.S. dollars.',\u001b[0m\u001b[48;2;240;255;240m                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'value': 3.0\u001b[0m\u001b[48;2;240;255;240m                                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'late payment', 'explanation': 'Up to $40.', 'value': 40.0},\u001b[0m\u001b[48;2;240;255;240m                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'name': 'return payment', 'explanation': 'Up to $40.', 'value': 40.0}\u001b[0m\u001b[48;2;240;255;240m                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ],\u001b[0m\u001b[48;2;240;255;240m                                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'interest_rates': [\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'account_type': 'purchase/my chase loan/balance transfer',\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'rate': 19.49\u001b[0m\u001b[48;2;240;255;240m                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'purchase', 'rate': 19.49},\u001b[0m\u001b[48;2;240;255;240m                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'my chase loan', 'rate': 19.49},\u001b[0m\u001b[48;2;240;255;240m                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'balance transfer', 'rate': 19.49},\u001b[0m\u001b[48;2;240;255;240m                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'cash advance', 'rate': 29.49},\u001b[0m\u001b[48;2;240;255;240m                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {'account_type': 'penalty', 'rate': 29.99}\u001b[0m\u001b[48;2;240;255;240m                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1626,7 +1461,7 @@
        "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 11,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1652,7 +1487,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.9"
+   "version": "3.12.1"
   },
   "orig_nbformat": 4
  },
diff --git a/docs/examples/input_validation.ipynb b/docs/examples/input_validation.ipynb
index 3018c2c07..302bc6a16 100644
--- a/docs/examples/input_validation.ipynb
+++ b/docs/examples/input_validation.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [
     {
@@ -38,7 +38,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 2,
    "metadata": {
     "is_executing": true
    },
@@ -73,18 +73,21 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 4,
    "metadata": {
     "is_executing": true
    },
    "outputs": [],
    "source": [
-    "import openai\n",
     "from guardrails.errors import ValidationError\n",
     "\n",
+    "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n",
+    "# import os\n",
+    "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n",
+    "\n",
     "try:\n",
     "    guard(\n",
-    "        openai.chat.completions.create,\n",
+    "        model=\"gpt-4o\"\n",
     "    )\n",
     "except ValidationError as e:\n",
     "    print(e)"
@@ -99,19 +102,9 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 5,
    "metadata": {},
    "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/zaydsimjee/workspace/guardrails/docs/examples/.venv/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3577: FutureWarning: The `with_prompt_validation` method is deprecated,\n",
-      "        and will be removed in 0.5.x. Instead, please use\n",
-      "        `Guard().use(YourValidator, on='prompt')`.\n",
-      "  exec(code_obj, self.user_global_ns, self.user_ns)\n"
-     ]
-    },
     {
      "name": "stdout",
      "output_type": "stream",
@@ -131,11 +124,11 @@
     "\n",
     "\n",
     "guard = Guard.from_pydantic(Pet)\n",
-    "guard.with_prompt_validation([TwoWords(on_fail=\"exception\")])\n",
+    "guard.use(TwoWords(on_fail=\"exception\"), on=\"prompt\")\n",
     "\n",
     "try:\n",
     "    guard(\n",
-    "        openai.chat.completions.create,\n",
+    "        model=\"gpt-4o\",\n",
     "        prompt=\"This is not two words\",\n",
     "    )\n",
     "except ValidationError as e:\n",
@@ -159,7 +152,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.12.1"
   }
  },
  "nbformat": 4,
diff --git a/docs/examples/json_function_calling_tools.ipynb b/docs/examples/json_function_calling_tools.ipynb
new file mode 100644
index 000000000..10016b257
--- /dev/null
+++ b/docs/examples/json_function_calling_tools.ipynb
@@ -0,0 +1,561 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mregex_match...\u001b[0m\n",
+      "✅Successfully installed guardrails/regex_match!\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "! guardrails hub install hub://guardrails/regex_match --quiet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "chat_history=\"\"\"\n",
+    "nelson and murdock: i need a pickup 797 9th Avenue, manila envelope, June 3 10:00am with dropoff 10:30am Courthouse, 61 Center Street C/O frank james\n",
+    "operator: quote - $23.00\n",
+    "neslon and murdock: perfect, we accept the quote\n",
+    "operator: 797 9th ave, 10:00am pickup comfirmed\n",
+    "abc flowers: i need a pickup of a flowers from abc flowers at 21 3rd street at 11:00am on june 2 with a dropoff at 75th Ave at 5:30pm same day\n",
+    "operator: 21 3rd street flowers quote - $14.50\n",
+    "abc flowers: accepted\n",
+    "polk and wardell: i need a pickup of a bagels from Bakers Co at 331 5th street at 11:00am on june 3 with a dropoff at 75th Ave at 5:30pm same day\n",
+    "operator: 331 5th street bagels quote - $34.50\n",
+    "polk and wardell: accepted\n",
+    "\"\"\"\n",
+    "\n",
+    "prompt = \"\"\"\n",
+    "From the chat exchanges below extract a schedule of deliveries.\n",
+    "Chats:\n",
+    "${chat_history}\n",
+    "\"\"\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
[\n",
+       "    {\n",
+       "        'type': 'function',\n",
+       "        'function': {\n",
+       "            'name': 'gd_response_tool',\n",
+       "            'description': 'A tool for generating responses to guardrails. It must be called last in every \n",
+       "response.',\n",
+       "            'parameters': {\n",
+       "                '$defs': {\n",
+       "                    'Delivery': {\n",
+       "                        'properties': {\n",
+       "                            'custome_name': {\n",
+       "                                'description': 'customer name',\n",
+       "                                'title': 'Custome Name',\n",
+       "                                'type': 'string',\n",
+       "                                'validators': [{'rail_alias': 'guardrails/regex_match'}]\n",
+       "                            },\n",
+       "                            'pickup_time': {\n",
+       "                                'description': 'date and time of pickup',\n",
+       "                                'title': 'Pickup Time',\n",
+       "                                'type': 'string'\n",
+       "                            },\n",
+       "                            'pickup_location': {\n",
+       "                                'description': 'address of pickup',\n",
+       "                                'title': 'Pickup Location',\n",
+       "                                'type': 'string'\n",
+       "                            },\n",
+       "                            'dropoff_time': {\n",
+       "                                'description': 'date and time of dropoff',\n",
+       "                                'title': 'Dropoff Time',\n",
+       "                                'type': 'string'\n",
+       "                            },\n",
+       "                            'dropoff_location': {\n",
+       "                                'description': 'address of dropoff',\n",
+       "                                'title': 'Dropoff Location',\n",
+       "                                'type': 'string'\n",
+       "                            },\n",
+       "                            'price': {\n",
+       "                                'description': 'price of delivery with currency symbol included',\n",
+       "                                'title': 'Price',\n",
+       "                                'type': 'string'\n",
+       "                            }\n",
+       "                        },\n",
+       "                        'required': [\n",
+       "                            'custome_name',\n",
+       "                            'pickup_time',\n",
+       "                            'pickup_location',\n",
+       "                            'dropoff_time',\n",
+       "                            'dropoff_location',\n",
+       "                            'price'\n",
+       "                        ],\n",
+       "                        'title': 'Delivery',\n",
+       "                        'type': 'object'\n",
+       "                    }\n",
+       "                },\n",
+       "                'properties': {\n",
+       "                    'deliveries': {'items': {'$ref': '#/$defs/Delivery'}, 'title': 'Deliveries', 'type': 'array'}\n",
+       "                },\n",
+       "                'required': ['deliveries'],\n",
+       "                'type': 'object',\n",
+       "                'title': 'Schedule'\n",
+       "            },\n",
+       "            'required': ['deliveries']\n",
+       "        }\n",
+       "    }\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m[\u001b[0m\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'function'\u001b[0m,\n", + " \u001b[32m'function'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'name'\u001b[0m: \u001b[32m'gd_response_tool'\u001b[0m,\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'A tool for generating responses to guardrails. It must be called last in every \u001b[0m\n", + "\u001b[32mresponse.'\u001b[0m,\n", + " \u001b[32m'parameters'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'$defs'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'Delivery'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'properties'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'custome_name'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'customer name'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Custome Name'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m,\n", + " \u001b[32m'validators'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'rail_alias'\u001b[0m: \u001b[32m'guardrails/regex_match'\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'pickup_time'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'date and time of pickup'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Pickup Time'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'pickup_location'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'address of pickup'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Pickup Location'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'dropoff_time'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'date and time of dropoff'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Dropoff Time'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'dropoff_location'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'address of dropoff'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Dropoff Location'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'price'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'price of delivery with currency symbol included'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Price'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'required'\u001b[0m: \u001b[1m[\u001b[0m\n", + " \u001b[32m'custome_name'\u001b[0m,\n", + " \u001b[32m'pickup_time'\u001b[0m,\n", + " \u001b[32m'pickup_location'\u001b[0m,\n", + " \u001b[32m'dropoff_time'\u001b[0m,\n", + " \u001b[32m'dropoff_location'\u001b[0m,\n", + " \u001b[32m'price'\u001b[0m\n", + " \u001b[1m]\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Delivery'\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'object'\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'properties'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'deliveries'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'items'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'$ref'\u001b[0m: \u001b[32m'#/$defs/Delivery'\u001b[0m\u001b[1m}\u001b[0m, \u001b[32m'title'\u001b[0m: \u001b[32m'Deliveries'\u001b[0m, \u001b[32m'type'\u001b[0m: \u001b[32m'array'\u001b[0m\u001b[1m}\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'required'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'deliveries'\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'object'\u001b[0m,\n", + " \u001b[32m'title'\u001b[0m: \u001b[32m'Schedule'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'required'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'deliveries'\u001b[0m\u001b[1m]\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from rich import print\n", + "from guardrails import Guard\n", + "from guardrails.hub import RegexMatch\n", + "from pydantic import BaseModel, Field\n", + "from typing import List\n", + "\n", + "NAME_REGEX = \"^[A-Z][a-z]+\\\\s[A-Z][a-z]+$\"\n", + "\n", + "class Delivery(BaseModel):\n", + " custome_name: str= Field(validators=[RegexMatch(regex=NAME_REGEX)], description=\"customer name\")\n", + " pickup_time: str= Field(description=\"date and time of pickup\")\n", + " pickup_location: str= Field(description=\"address of pickup\")\n", + " dropoff_time: str= Field(description=\"date and time of dropoff\")\n", + " dropoff_location: str= Field(description=\"address of dropoff\")\n", + " price: str = Field(description=\"price of delivery with currency symbol included\")\n", + "\n", + "class Schedule(BaseModel):\n", + " deliveries: List[Delivery]\n", + "\n", + "pydantic_guard = Guard.from_pydantic(Schedule)\n", + "\n", + "# Generate the function calling tool and add it to the list\n", + "pydantic_guard_tools = pydantic_guard.json_function_calling_tool([])\n", + "\n", + "print(pydantic_guard_tools)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rail = \"\"\"\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "\"\"\"\n", + "\n", + "rail_guard = Guard.from_rail_string(rail)\n", + "\n", + "\n", + "# Generate the function calling tool and add it to the list\n", + "rail_guard_tools = rail_guard.json_function_calling_tool([])\n", + "\n", + "print(rail_guard_tools)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='4586524096',\n",
+       "    raw_llm_output='{\"deliveries\":[{\"custome_name\":\"nelson and murdock\",\"pickup_time\":\"June 3 \n",
+       "10:00am\",\"pickup_location\":\"797 9th Avenue\",\"dropoff_time\":\"June 3 10:30am\",\"dropoff_location\":\"Courthouse, 61 \n",
+       "Center Street C/O frank james\",\"price\":\"$23.00\"},{\"custome_name\":\"abc flowers\",\"pickup_time\":\"June 2 \n",
+       "11:00am\",\"pickup_location\":\"21 3rd street\",\"dropoff_time\":\"June 2 5:30pm\",\"dropoff_location\":\"75th \n",
+       "Ave\",\"price\":\"$14.50\"},{\"custome_name\":\"polk and wardell\",\"pickup_time\":\"June 3 11:00am\",\"pickup_location\":\"331 5th\n",
+       "street\",\"dropoff_time\":\"June 3 5:30pm\",\"dropoff_location\":\"75th Ave\",\"price\":\"$34.50\"}]}',\n",
+       "    validated_output={\n",
+       "        'deliveries': [\n",
+       "            {\n",
+       "                'custome_name': 'nelson and murdock',\n",
+       "                'pickup_time': 'June 3 10:00am',\n",
+       "                'pickup_location': '797 9th Avenue',\n",
+       "                'dropoff_time': 'June 3 10:30am',\n",
+       "                'dropoff_location': 'Courthouse, 61 Center Street C/O frank james',\n",
+       "                'price': '$23.00'\n",
+       "            },\n",
+       "            {\n",
+       "                'custome_name': 'abc flowers',\n",
+       "                'pickup_time': 'June 2 11:00am',\n",
+       "                'pickup_location': '21 3rd street',\n",
+       "                'dropoff_time': 'June 2 5:30pm',\n",
+       "                'dropoff_location': '75th Ave',\n",
+       "                'price': '$14.50'\n",
+       "            },\n",
+       "            {\n",
+       "                'custome_name': 'polk and wardell',\n",
+       "                'pickup_time': 'June 3 11:00am',\n",
+       "                'pickup_location': '331 5th street',\n",
+       "                'dropoff_time': 'June 3 5:30pm',\n",
+       "                'dropoff_location': '75th Ave',\n",
+       "                'price': '$34.50'\n",
+       "            }\n",
+       "        ]\n",
+       "    },\n",
+       "    reask=None,\n",
+       "    validation_passed=False,\n",
+       "    error=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'4586524096'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"deliveries\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"custome_name\":\"nelson and murdock\",\"pickup_time\":\"June 3 \u001b[0m\n", + "\u001b[32m10:00am\",\"pickup_location\":\"797 9th Avenue\",\"dropoff_time\":\"June 3 10:30am\",\"dropoff_location\":\"Courthouse, 61 \u001b[0m\n", + "\u001b[32mCenter Street C/O frank james\",\"price\":\"$23.00\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m,\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"custome_name\":\"abc flowers\",\"pickup_time\":\"June 2 \u001b[0m\n", + "\u001b[32m11:00am\",\"pickup_location\":\"21 3rd street\",\"dropoff_time\":\"June 2 5:30pm\",\"dropoff_location\":\"75th \u001b[0m\n", + "\u001b[32mAve\",\"price\":\"$14.50\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m,\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"custome_name\":\"polk and wardell\",\"pickup_time\":\"June 3 11:00am\",\"pickup_location\":\"331 5th\u001b[0m\n", + "\u001b[32mstreet\",\"dropoff_time\":\"June 3 5:30pm\",\"dropoff_location\":\"75th Ave\",\"price\":\"$34.50\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", + " \u001b[33mvalidated_output\u001b[0m=\u001b[1m{\u001b[0m\n", + " \u001b[32m'deliveries'\u001b[0m: \u001b[1m[\u001b[0m\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m'custome_name'\u001b[0m: \u001b[32m'nelson and murdock'\u001b[0m,\n", + " \u001b[32m'pickup_time'\u001b[0m: \u001b[32m'June 3 10:00am'\u001b[0m,\n", + " \u001b[32m'pickup_location'\u001b[0m: \u001b[32m'797 9th Avenue'\u001b[0m,\n", + " \u001b[32m'dropoff_time'\u001b[0m: \u001b[32m'June 3 10:30am'\u001b[0m,\n", + " \u001b[32m'dropoff_location'\u001b[0m: \u001b[32m'Courthouse, 61 Center Street C/O frank james'\u001b[0m,\n", + " \u001b[32m'price'\u001b[0m: \u001b[32m'$23.00'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m'custome_name'\u001b[0m: \u001b[32m'abc flowers'\u001b[0m,\n", + " \u001b[32m'pickup_time'\u001b[0m: \u001b[32m'June 2 11:00am'\u001b[0m,\n", + " \u001b[32m'pickup_location'\u001b[0m: \u001b[32m'21 3rd street'\u001b[0m,\n", + " \u001b[32m'dropoff_time'\u001b[0m: \u001b[32m'June 2 5:30pm'\u001b[0m,\n", + " \u001b[32m'dropoff_location'\u001b[0m: \u001b[32m'75th Ave'\u001b[0m,\n", + " \u001b[32m'price'\u001b[0m: \u001b[32m'$14.50'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[1m{\u001b[0m\n", + " \u001b[32m'custome_name'\u001b[0m: \u001b[32m'polk and wardell'\u001b[0m,\n", + " \u001b[32m'pickup_time'\u001b[0m: \u001b[32m'June 3 11:00am'\u001b[0m,\n", + " \u001b[32m'pickup_location'\u001b[0m: \u001b[32m'331 5th street'\u001b[0m,\n", + " \u001b[32m'dropoff_time'\u001b[0m: \u001b[32m'June 3 5:30pm'\u001b[0m,\n", + " \u001b[32m'dropoff_location'\u001b[0m: \u001b[32m'75th Ave'\u001b[0m,\n", + " \u001b[32m'price'\u001b[0m: \u001b[32m'$34.50'\u001b[0m\n", + " \u001b[1m}\u001b[0m\n", + " \u001b[1m]\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidation_passed\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "response = pydantic_guard(\n", + " model=\"gpt-4o\",\n", + " instructions=\"You are a helpful assistant.\",\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={\"chat_history\": chat_history},\n", + " tools=pydantic_guard_tools,\n", + " tool_choice=\"required\",\n", + ")\n", + "\n", + "print(response)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Logs\n",
+       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ From the chat exchanges below extract a schedule of deliveries.                                         │ │\n",
+       "    │ │ Chats:                                                                                                  │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ nelson and murdock: i need a pickup 797 9th Avenue, manila envelope, June 3 10:00am with dropoff        │ │\n",
+       "    │ │ 10:30am Courthouse, 61 Center Street C/O frank james                                                    │ │\n",
+       "    │ │ operator: quote - $23.00                                                                                │ │\n",
+       "    │ │ neslon and murdock: perfect, we accept the quote                                                        │ │\n",
+       "    │ │ operator: 797 9th ave, 10:00am pickup comfirmed                                                         │ │\n",
+       "    │ │ abc flowers: i need a pickup of a flowers from abc flowers at 21 3rd street at 11:00am on june 2 with a │ │\n",
+       "    │ │ dropoff at 75th Ave at 5:30pm same day                                                                  │ │\n",
+       "    │ │ operator: 21 3rd street flowers quote - $14.50                                                          │ │\n",
+       "    │ │ abc flowers: accepted                                                                                   │ │\n",
+       "    │ │ polk and wardell: i need a pickup of a bagels from Bakers Co at 331 5th street at 11:00am on june 3     │ │\n",
+       "    │ │ with a dropoff at 75th Ave at 5:30pm same day                                                           │ │\n",
+       "    │ │ operator: 331 5th street bagels quote - $34.50                                                          │ │\n",
+       "    │ │ polk and wardell: accepted                                                                              │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
+       "    │ │ You are a helpful assistant.                                                                            │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ {\"deliveries\":[{\"custome_name\":\"nelson and murdock\",\"pickup_time\":\"June 3                               │ │\n",
+       "    │ │ 10:00am\",\"pickup_location\":\"797 9th Avenue\",\"dropoff_time\":\"June 3                                      │ │\n",
+       "    │ │ 10:30am\",\"dropoff_location\":\"Courthouse, 61 Center Street C/O frank                                     │ │\n",
+       "    │ │ james\",\"price\":\"$23.00\"},{\"custome_name\":\"abc flowers\",\"pickup_time\":\"June 2                            │ │\n",
+       "    │ │ 11:00am\",\"pickup_location\":\"21 3rd street\",\"dropoff_time\":\"June 2 5:30pm\",\"dropoff_location\":\"75th      │ │\n",
+       "    │ │ Ave\",\"price\":\"$14.50\"},{\"custome_name\":\"polk and wardell\",\"pickup_time\":\"June 3                         │ │\n",
+       "    │ │ 11:00am\",\"pickup_location\":\"331 5th street\",\"dropoff_time\":\"June 3 5:30pm\",\"dropoff_location\":\"75th     │ │\n",
+       "    │ │ Ave\",\"price\":\"$34.50\"}]}                                                                                │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │     'deliveries': [                                                                                     │ │\n",
+       "    │ │         {                                                                                               │ │\n",
+       "    │ │             'custome_name': 'nelson and murdock',                                                       │ │\n",
+       "    │ │             'pickup_time': 'June 3 10:00am',                                                            │ │\n",
+       "    │ │             'pickup_location': '797 9th Avenue',                                                        │ │\n",
+       "    │ │             'dropoff_time': 'June 3 10:30am',                                                           │ │\n",
+       "    │ │             'dropoff_location': 'Courthouse, 61 Center Street C/O frank james',                         │ │\n",
+       "    │ │             'price': '$23.00'                                                                           │ │\n",
+       "    │ │         },                                                                                              │ │\n",
+       "    │ │         {                                                                                               │ │\n",
+       "    │ │             'custome_name': 'abc flowers',                                                              │ │\n",
+       "    │ │             'pickup_time': 'June 2 11:00am',                                                            │ │\n",
+       "    │ │             'pickup_location': '21 3rd street',                                                         │ │\n",
+       "    │ │             'dropoff_time': 'June 2 5:30pm',                                                            │ │\n",
+       "    │ │             'dropoff_location': '75th Ave',                                                             │ │\n",
+       "    │ │             'price': '$14.50'                                                                           │ │\n",
+       "    │ │         },                                                                                              │ │\n",
+       "    │ │         {                                                                                               │ │\n",
+       "    │ │             'custome_name': 'polk and wardell',                                                         │ │\n",
+       "    │ │             'pickup_time': 'June 3 11:00am',                                                            │ │\n",
+       "    │ │             'pickup_location': '331 5th street',                                                        │ │\n",
+       "    │ │             'dropoff_time': 'June 3 5:30pm',                                                            │ │\n",
+       "    │ │             'dropoff_location': '75th Ave',                                                             │ │\n",
+       "    │ │             'price': '$34.50'                                                                           │ │\n",
+       "    │ │         }                                                                                               │ │\n",
+       "    │ │     ]                                                                                                   │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "Logs\n", + "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mFrom the chat exchanges below extract a schedule of deliveries.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mChats:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mnelson and murdock: i need a pickup 797 9th Avenue, manila envelope, June 3 10:00am with dropoff \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m10:30am Courthouse, 61 Center Street C/O frank james\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255moperator: quote - $23.00\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mneslon and murdock: perfect, we accept the quote\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255moperator: 797 9th ave, 10:00am pickup comfirmed\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabc flowers: i need a pickup of a flowers from abc flowers at 21 3rd street at 11:00am on june 2 with a\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdropoff at 75th Ave at 5:30pm same day\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255moperator: 21 3rd street flowers quote - $14.50\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mabc flowers: accepted\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mpolk and wardell: i need a pickup of a bagels from Bakers Co at 331 5th street at 11:00am on june 3 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwith a dropoff at 75th Ave at 5:30pm same day\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255moperator: 331 5th street bagels quote - $34.50\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mpolk and wardell: accepted\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\"deliveries\":[{\"custome_name\":\"nelson and murdock\",\"pickup_time\":\"June 3 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m10:00am\",\"pickup_location\":\"797 9th Avenue\",\"dropoff_time\":\"June 3 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m10:30am\",\"dropoff_location\":\"Courthouse, 61 Center Street C/O frank \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mjames\",\"price\":\"$23.00\"},{\"custome_name\":\"abc flowers\",\"pickup_time\":\"June 2 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m11:00am\",\"pickup_location\":\"21 3rd street\",\"dropoff_time\":\"June 2 5:30pm\",\"dropoff_location\":\"75th \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mAve\",\"price\":\"$14.50\"},{\"custome_name\":\"polk and wardell\",\"pickup_time\":\"June 3 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m11:00am\",\"pickup_location\":\"331 5th street\",\"dropoff_time\":\"June 3 5:30pm\",\"dropoff_location\":\"75th \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mAve\",\"price\":\"$34.50\"}]}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'deliveries': [\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m {\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'custome_name': 'nelson and murdock',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'pickup_time': 'June 3 10:00am',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'pickup_location': '797 9th Avenue',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'dropoff_time': 'June 3 10:30am',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'dropoff_location': 'Courthouse, 61 Center Street C/O frank james',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'price': '$23.00'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m },\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m {\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'custome_name': 'abc flowers',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'pickup_time': 'June 2 11:00am',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'pickup_location': '21 3rd street',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'dropoff_time': 'June 2 5:30pm',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'dropoff_location': '75th Ave',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'price': '$14.50'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m },\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m {\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'custome_name': 'polk and wardell',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'pickup_time': 'June 3 11:00am',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'pickup_location': '331 5th street',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'dropoff_time': 'June 3 5:30pm',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'dropoff_location': '75th Ave',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'price': '$34.50'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m }\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m ]\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pydantic_guard.history.last.tree" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/lite_llm_defaults.ipynb b/docs/examples/lite_llm_defaults.ipynb new file mode 100644 index 000000000..acddd90fa --- /dev/null +++ b/docs/examples/lite_llm_defaults.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mregex_match...\u001b[0m\n", + "✅Successfully installed guardrails/regex_match!\n", + "\n", + "\n" + ] + } + ], + "source": [ + "! guardrails hub install hub://guardrails/regex_match --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='6112958560',\n",
+       "    raw_llm_output=\"As of my last update in 2023, Jupiter has 95 confirmed moons. The number of known moons can \n",
+       "change as new moons are discovered and confirmed, so it's always a good idea to check the latest information from \n",
+       "reliable sources such as NASA or other astronomical organizations.\",\n",
+       "    validated_output=\"As of my last update in 2023, Jupiter has 95 confirmed moons. The number of known moons can \n",
+       "change as new moons are discovered and confirmed, so it's always a good idea to check the latest information from \n",
+       "reliable sources such as NASA or other astronomical organizations.\",\n",
+       "    reask=None,\n",
+       "    validation_passed=True,\n",
+       "    error=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'6112958560'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m\"As\u001b[0m\u001b[32m of my last update in 2023, Jupiter has 95 confirmed moons. The number of known moons can \u001b[0m\n", + "\u001b[32mchange as new moons are discovered and confirmed, so it's always a good idea to check the latest information from \u001b[0m\n", + "\u001b[32mreliable sources such as NASA or other astronomical organizations.\"\u001b[0m,\n", + " \u001b[33mvalidated_output\u001b[0m=\u001b[32m\"As\u001b[0m\u001b[32m of my last update in 2023, Jupiter has 95 confirmed moons. The number of known moons can \u001b[0m\n", + "\u001b[32mchange as new moons are discovered and confirmed, so it's always a good idea to check the latest information from \u001b[0m\n", + "\u001b[32mreliable sources such as NASA or other astronomical organizations.\"\u001b[0m,\n", + " \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidation_passed\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from rich import print\n", + "from guardrails import Guard\n", + "from guardrails.hub import RegexMatch\n", + "\n", + "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "guard = Guard().use(RegexMatch(\"95\", match_type=\"search\"))\n", + "\n", + "response = guard(\n", + " model=\"gpt-4o\",\n", + " instructions=\"You are a helpful assistant.\",\n", + " prompt=\"How many moons does jupiter have?\",\n", + " messages=[{\n", + " \"role\": \"system\",\n", + " \"content\": \"You are a helpful assistant.\"\n", + " },{\n", + " \"role\": \"user\",\n", + " \"content\": \"How many moons does jupiter have?\"\n", + " }]\n", + ")\n", + "\n", + "print(response)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/llamaindex-output-parsing.ipynb b/docs/examples/llamaindex-output-parsing.ipynb index 53121f5f6..80fbfd2aa 100644 --- a/docs/examples/llamaindex-output-parsing.ipynb +++ b/docs/examples/llamaindex-output-parsing.ipynb @@ -374,7 +374,8 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3" + "pygments_lexer": "ipython3", + "version": "3.12.1" } }, "nbformat": 4, diff --git a/docs/examples/no_secrets_in_generated_text.ipynb b/docs/examples/no_secrets_in_generated_text.ipynb index 05f0ecc16..8be7ef687 100644 --- a/docs/examples/no_secrets_in_generated_text.ipynb +++ b/docs/examples/no_secrets_in_generated_text.ipynb @@ -45,26 +45,7 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n", - "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/guardrails/validators/__init__.py:51: FutureWarning: \n", - " Importing validators from `guardrails.validators` is deprecated.\n", - " All validators are now available in the Guardrails Hub. Please install\n", - " and import them from the hub instead. All validators will be\n", - " removed from this module in the next major release.\n", - "\n", - " Install with: `guardrails hub install hub:///`\n", - " Import as: from guardrails.hub import `ValidatorName`\n", - " \n", - " warn(\n" - ] - } - ], + "outputs": [], "source": [ "from guardrails.validators import Validator, register_validator, PassResult, FailResult, ValidationResult\n", "\n", @@ -117,7 +98,7 @@ "\n", "How do I use OpenAI's Completion API?\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\n", "\n", "\n", @@ -125,6 +106,11 @@ "\"\"\"" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -145,7 +131,7 @@ "\n", "How do I use OpenAI's Completion API?\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\"\"\"\n", "\n", "class ScrubbedCode(BaseModel):\n", @@ -187,16 +173,7 @@ "cell_type": "code", "execution_count": 5, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/guardrails/prompt/base_prompt.py:59: FutureWarning: Prompt Primitives are moving! To keep the same behaviour, switch from `json` constants to `xml` constants. Example: ${gr.complete_json_suffix} -> ${gr.complete_xml_suffix}\n", - " warn(\n" - ] - } - ], + "outputs": [], "source": [ "guard = gd.Guard.from_rail_string(rail_str)" ] @@ -212,18 +189,43 @@ "cell_type": "code", "execution_count": 6, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/guardrails/prompt/base_prompt.py:59: FutureWarning: Prompt Primitives are moving! To keep the same behaviour, switch from `json` constants to `xml` constants. Example: ${gr.complete_json_suffix} -> ${gr.complete_xml_suffix}\n", - " warn(\n" - ] - } - ], + "outputs": [], + "source": [ + "guard = gd.Guard.from_pydantic(output_class=ScrubbedCode)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Wrap the LLM API call with `Guard`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `guard` wrapper returns the raw_llm_respose (which is a simple string), and the validated and corrected output (which is a dictionary).\n", + "\n", + "We can see that the output is a dictionary with the correct schema and types." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], "source": [ - "guard = gd.Guard.from_pydantic(output_class=ScrubbedCode, prompt=prompt)" + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "raw_llm_response, validated_response, *rest = guard(\n", + " model=\"gpt-3.5-turbo-instruct\",\n", + " max_tokens=3548,\n", + " temperature=0,\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + ")" ] }, { @@ -231,22 +233,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see the prompt that will be sent to the LLM." + "We can see the prompt that was sent to the LLM." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 17, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/w2/ssf16z690zd7_4dggw0y5s_m0000gn/T/ipykernel_82075/3983563700.py:1: DeprecationWarning: 'Guard.base_prompt' is deprecated and will be removed in versions 0.5.x and beyond. Use 'Guard.history.last.prompt' instead.\n", - " print(guard.base_prompt)\n" - ] - }, { "data": { "text/html": [ @@ -258,11 +252,10 @@ "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "<output>\n", - " <string name=\"api_help\" description=\"Show an example curl command for using openai Completion API\" \n", - "format=\"no-code-secrets\"/>\n", + " <string description=\"Show an example curl command for using openai Completion API\" format=\"no-code-secrets\" \n", + "name=\"api_help\" required=\"true\"></string>\n", "</output>\n", "\n", - "\n", "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n", "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n", "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n", @@ -286,11 +279,10 @@ "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", "\n", - "\n", "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", @@ -310,51 +302,28 @@ } ], "source": [ - "print(guard.base_prompt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Wrap the LLM API call with `Guard`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `guard` wrapper returns the raw_llm_respose (which is a simple string), and the validated and corrected output (which is a dictionary).\n", - "\n", - "We can see that the output is a dictionary with the correct schema and types." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.completions.create, model=\"gpt-3.5-turbo-instruct\", max_tokens=2048, temperature=0\n", - ")" + "print(guard.history.last.iterations.first.inputs.msg_history[0][\"content\"])" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
{'api_help': 'Show an example curl command for using openai Completion API'}\n",
+       "
{\n",
+       "    'api_help': 'curl -X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer YOUR_API_KEY\" -d \n",
+       "\\'{\"prompt\": \"The quick brown fox\", \"max_tokens\": 5}\\' \"https://api.openai.com/v1/engines/davinci/completions\"'\n",
+       "}\n",
        "
\n" ], "text/plain": [ - "\u001b[1m{\u001b[0m\u001b[32m'api_help'\u001b[0m: \u001b[32m'Show an example curl command for using openai Completion API'\u001b[0m\u001b[1m}\u001b[0m\n" + "\u001b[1m{\u001b[0m\n", + " \u001b[32m'api_help'\u001b[0m: \u001b[32m'curl -X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer YOUR_API_KEY\" -d \u001b[0m\n", + "\u001b[32m\\'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"prompt\": \"The quick brown fox\", \"max_tokens\": 5\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\' \"https://api.openai.com/v1/engines/davinci/completions\"'\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, @@ -367,109 +336,295 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "│   │ │ No prompt                                                                                               │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "│   │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "│   │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "│   │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "│   │ │ │ user │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ How do I use OpenAI's Completion API?                                                        │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "│   │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ <output>                                                                                     │ │ │\n",
+       "│   │ │ │      │   <string description=\"Show an example curl command for using openai Completion API\"         │ │ │\n",
+       "│   │ │ │      │ format=\"no-code-secrets\" name=\"api_help\" required=\"true\"></string>                           │ │ │\n",
+       "│   │ │ │      │ </output>                                                                                    │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "│   │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "│   │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "│   │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "│   │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "│   │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "│   │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "│   │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "│   │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "│   │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "│   │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "│   │ │ {                                                                                                       │ │\n",
+       "│   │ │   \"api_help\": {                                                                                         │ │\n",
+       "│   │ │     \"description\": \"Show an example curl command for using openai Completion API\",                      │ │\n",
+       "│   │ │     \"format\": \"no-code-secrets\",                                                                        │ │\n",
+       "│   │ │     \"name\": \"api_help\",                                                                                 │ │\n",
+       "│   │ │     \"required\": true                                                                                    │ │\n",
+       "│   │ │   }                                                                                                     │ │\n",
+       "│   │ │ }                                                                                                       │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "│   │ │ SkeletonReAsk(                                                                                          │ │\n",
+       "│   │ │     incorrect_value={'api_help': {}},                                                                   │ │\n",
+       "│   │ │     fail_results=[                                                                                      │ │\n",
+       "│   │ │         FailResult(                                                                                     │ │\n",
+       "│   │ │             outcome='fail',                                                                             │ │\n",
+       "│   │ │             error_message='JSON does not match schema:\\n{\\n  \"$.api_help\": [\\n    \"{} is not of type    │ │\n",
+       "│   │ │ \\'string\\'\"\\n  ]\\n}',                                                                                   │ │\n",
+       "│   │ │             fix_value=None,                                                                             │ │\n",
+       "│   │ │             error_spans=None,                                                                           │ │\n",
+       "│   │ │             metadata=None,                                                                              │ │\n",
+       "│   │ │             validated_chunk=None                                                                        │ │\n",
+       "│   │ │         )                                                                                               │ │\n",
+       "│   │ │     ],                                                                                                  │ │\n",
+       "│   │ │     additional_properties={}                                                                            │ │\n",
+       "│   │ │ )                                                                                                       │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
        "    │ │                                                                                                         │ │\n",
+       "    │ │ I was given the following JSON response, which had problems due to incorrect values.                    │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"incorrect_value\": {                                                                                  │ │\n",
+       "    │ │     \"api_help\": {}                                                                                      │ │\n",
+       "    │ │   },                                                                                                    │ │\n",
+       "    │ │   \"error_messages\": [                                                                                   │ │\n",
+       "    │ │     \"JSON does not match schema:\\n{\\n  \\\"$.api_help\\\": [\\n    \\\"{} is not of type 'string'\\\"\\n  ]\\n}\"   │ │\n",
+       "    │ │   ]                                                                                                     │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │ How do I use OpenAI's Completion API?                                                                   │ │\n",
+       "    │ │ Help me correct the incorrect values based on the given error messages.                                 │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
        "    │ │ it into.                                                                                                │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <string name=\"api_help\" description=\"Show an example curl command for using openai Completion API\"  │ │\n",
-       "    │ │ format=\"no-code-secrets\"/>                                                                              │ │\n",
+       "    │ │   <string description=\"Show an example curl command for using openai Completion API\"                    │ │\n",
+       "    │ │ format=\"no-code-secrets\" name=\"api_help\" required=\"true\"></string>                                      │ │\n",
        "    │ │ </output>                                                                                               │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
        "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
        "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
        "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
        "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
        "    │ │ enter `null`.                                                                                           │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Json Output:                                                                                            │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ Here's an example of the structure:                                                                     │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"api_help\": \"spend\"                                                                                   │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ You are a helpful assistant only capable of communicating with valid JSON, and no other text.           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
+       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
+       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
+       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
+       "    │ │ enter `null`.                                                                                           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
+       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "    │ │ etc.]}`                                                                                                 │ │\n",
+       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
        "    │ │ No message history.                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
        "    │ │ {                                                                                                       │ │\n",
-       "    │ │     \"api_help\": \"Show an example curl command for using openai Completion API\"                          │ │\n",
+       "    │ │   \"api_help\": \"curl -X POST -H \\\"Content-Type: application/json\\\" -H \\\"Authorization: Bearer            │ │\n",
+       "    │ │ YOUR_API_KEY\\\" -d '{\\\"prompt\\\": \\\"The quick brown fox\\\", \\\"max_tokens\\\": 5}'                            │ │\n",
+       "    │ │ \\\"https://api.openai.com/v1/engines/davinci/completions\\\"\"                                              │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ {'api_help': 'Show an example curl command for using openai Completion API'}                            │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │     'api_help': 'curl -X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer             │ │\n",
+       "    │ │ YOUR_API_KEY\" -d \\'{\"prompt\": \"The quick brown fox\", \"max_tokens\": 5}\\'                                 │ │\n",
+       "    │ │ \"https://api.openai.com/v1/engines/davinci/completions\"'                                                │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
        "
\n" ], "text/plain": [ "Logs\n", - "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + "│ │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHow do I use OpenAI's Completion API? \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE', \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index': \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"api_help\": {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"description\": \"Show an example curl command for using openai Completion API\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"no-code-secrets\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"api_help\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"required\": true\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mSkeletonReAsk(\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m incorrect_value={'api_help': {}},\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m fail_results=[\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m FailResult(\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m outcome='fail',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m error_message='JSON does not match schema:\\n{\\n \"$.api_help\": [\\n \"{} is not of type \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m\\'string\\'\"\\n ]\\n}',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m fix_value=None,\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m error_spans=None,\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m metadata=None,\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m validated_chunk=None\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m )\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m ],\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m additional_properties={}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m)\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n", + "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n", " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mI was given the following JSON response, which had problems due to incorrect values.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"incorrect_value\": {\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"api_help\": {}\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m },\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"error_messages\": [\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"JSON does not match schema:\\n{\\n \\\"$.api_help\\\": [\\n \\\"{} is not of type 'string'\\\"\\n ]\\n}\"\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m ]\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHow do I use OpenAI's Completion API?\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHelp me correct the incorrect values based on the given error messages.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mJson Output:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere's an example of the structure:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"api_help\": \"spend\"\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant only capable of communicating with valid JSON, and no other text.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242menter `null`.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242metc.]}`\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"api_help\": \"Show an example curl command for using openai Completion API\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"api_help\": \"curl -X POST -H \\\"Content-Type: application/json\\\" -H \\\"Authorization: Bearer \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mYOUR_API_KEY\\\" -d '{\\\"prompt\\\": \\\"The quick brown fox\\\", \\\"max_tokens\\\": 5}' \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m\\\"https://api.openai.com/v1/engines/davinci/completions\\\"\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'api_help': 'Show an example curl command for using openai Completion API'}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'api_help': 'curl -X POST -H \"Content-Type: application/json\" -H \"Authorization: Bearer \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mYOUR_API_KEY\" -d \\'{\"prompt\": \"The quick brown fox\", \"max_tokens\": 5}\\' \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m\"https://api.openai.com/v1/engines/davinci/completions\"'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] @@ -499,7 +654,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.12.1" }, "orig_nbformat": 4, "vscode": { diff --git a/docs/examples/provenance.ipynb b/docs/examples/provenance.ipynb index 1b9e5e45a..3297601c0 100644 --- a/docs/examples/provenance.ipynb +++ b/docs/examples/provenance.ipynb @@ -2,12 +2,31 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mprovenance_embeddings...\u001b[0m\n", + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n", + "✅Successfully installed guardrails/provenance_embeddings!\n", + "\n", + "\n", + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mprovenance_llm...\u001b[0m\n", + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n", + "✅Successfully installed guardrails/provenance_llm!\n", + "\n", + "\n" + ] + } + ], "source": [ - "!guardrails hub install hub://guardrails/provenance_embeddings\n", - "!guardrails hub install hub://guardrails/provenance_llm" + "!guardrails hub install hub://guardrails/provenance_embeddings --quiet\n", + "!guardrails hub install hub://guardrails/provenance_llm --quiet" ] }, { @@ -57,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -269,9 +288,18 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from tqdm.autonotebook import tqdm, trange\n" + ] + } + ], "source": [ "# Create an embedding function that uses a cohere model to embed the text\n", "from rich import print\n", @@ -310,7 +338,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -332,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -389,7 +417,7 @@ " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] }, - "execution_count": 25, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -414,7 +442,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -457,7 +485,7 @@ " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] }, - "execution_count": 16, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -496,7 +524,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -518,7 +546,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -540,11 +568,11 @@ " │ │ important to clean the litter box regularly and to provide a safe and healthy environment for the cat. │ │\n", " │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n", " │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n", - " │ │ 'To retrain a cat to use the litter box, put its litter box in a low traffic area with at least 2 exits │ │\n", + " │ │ To retrain a cat to use the litter box, put its litter box in a low traffic area with at least 2 exits │ │\n", " │ │ so the cat doesn’t feel cornered. Find the right litterbox for your cat, as well as the right litter. │ │\n", " │ │ Place the litterbox in a good spot, away from heavily trafficked and noisy areas. Keep the litterbox │ │\n", " │ │ very clean, and do not punish the cat or confine her to just one room. Once training is complete, it is │ │\n", - " │ │ important to clean the litter box regularly and to provide a safe and healthy environment for the cat.' │ │\n", + " │ │ important to clean the litter box regularly and to provide a safe and healthy environment for the cat. │ │\n", " │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n", " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n", "
\n" @@ -566,16 +594,16 @@ " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mimportant to clean the litter box regularly and to provide a safe and healthy environment for the cat.\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m'To retrain a cat to use the litter box, put its litter box in a low traffic area with at least 2 exits\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mTo retrain a cat to use the litter box, put its litter box in a low traffic area with at least 2 exits \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mso the cat doesn’t feel cornered. Find the right litterbox for your cat, as well as the right litter. \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mPlace the litterbox in a good spot, away from heavily trafficked and noisy areas. Keep the litterbox \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mvery clean, and do not punish the cat or confine her to just one room. Once training is complete, it is\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mimportant to clean the litter box regularly and to provide a safe and healthy environment for the cat.'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mimportant to clean the litter box regularly and to provide a safe and healthy environment for the cat.\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] }, - "execution_count": 18, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -594,7 +622,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -637,7 +665,7 @@ " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] }, - "execution_count": 19, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -677,7 +705,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git a/docs/examples/recipe_generation.ipynb b/docs/examples/recipe_generation.ipynb index 7996df62e..80a3dea36 100644 --- a/docs/examples/recipe_generation.ipynb +++ b/docs/examples/recipe_generation.ipynb @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -46,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -90,7 +90,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -119,7 +119,7 @@ "\n", "\n", "Generate a recipe for vegan mac and cheese.\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\n", "\n", "\n", @@ -135,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -145,7 +145,7 @@ "\n", "prompt = \"\"\"\n", "Generate a recipe for vegan mac and cheese.\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\"\"\"\n", "\n", "class Ingredient(BaseModel):\n", @@ -197,57 +197,84 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "guard = gd.Guard.from_rail_string(rail_str)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From the Pydantic model:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/home/zayd/workspace/guardrails/.venv/lib/python3.9/site-packages/guardrails/validatorsattr.py:285: UserWarning: Validator 1-indexed is not valid for element integer.\n", - " warnings.warn(\n", - "\n", - "/home/zayd/workspace/guardrails/.venv/lib/python3.9/site-packages/guardrails/validatorsattr.py:285: UserWarning: Validator units-imperial is not valid for element float.\n", - " warnings.warn(\n", - "\n", - "/home/zayd/workspace/guardrails/.venv/lib/python3.9/site-packages/guardrails/validatorsattr.py:285: UserWarning: Validator units-imperial is not valid for element string.\n", - " warnings.warn(\n", - "\n" + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", + " from tqdm.autonotebook import tqdm, trange\n", + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/guardrails/validator_base.py:152: UserWarning: Validator with id 1-indexed was not found in the registry! Ignoring...\n", + " warn(f\"Validator with id {name} was not found in the registry! Ignoring...\")\n", + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/guardrails/validator_base.py:152: UserWarning: Validator with id units-imperial was not found in the registry! Ignoring...\n", + " warn(f\"Validator with id {name} was not found in the registry! Ignoring...\")\n" ] } ], "source": [ - "guard = gd.Guard.from_rail_string(rail_str)" + "guard = gd.Guard.from_pydantic(output_class=Recipe)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "From the Pydantic model:" + "As we can see, a few formatters weren't supported. These formatters won't be enforced in the output, but this information can still be used to generate a prompt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Wrap the LLM API call with `Guard`" ] }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "guard = gd.Guard.from_pydantic(output_class=Recipe, prompt=prompt)" + "# Add your OPENAI_API_KEY as an environment variable if it's not already set\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "raw_llm_response, validated_response, *rest = guard(\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " max_tokens=2048,\n", + " temperature=0,\n", + " model=\"gpt-4\"\n", + ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "As we can see, a few formatters weren't supported. These formatters won't be enforced in the output, but this information can still be used to generate a prompt.\n", - "\n", - "We see the prompt that will be sent to the LLM. The `{document}` is substituted with the user provided value at runtime." + "We can see the prompt that was sent to the LLM. The `{document}` param was substituted with the user provided value at runtime." ] }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -259,25 +286,24 @@ "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "<output>\n", - " <list name=\"ingredients\" description=\"What are the ingredients for the recipe?\">\n", - " <object>\n", - " <integer name=\"index\" format=\"1-indexed\"/>\n", - " <string name=\"name\" format=\"is-vegan\"/>\n", - " <string name=\"brand\" description=\"Suggested brand for the ingredient (if any)\"/>\n", - " <bool name=\"optional\" description=\"Is the ingredient necessary?\"/>\n", - " <float name=\"quantity\" description=\"how much of this ingredient to use\" format=\"units-imperial\"/>\n", - " <string name=\"units\" format=\"units-imperial\"/>\n", - " </object>\n", - " </list>\n", - " <list name=\"instructions\" description=\"What are the instructions for the recipe?\">\n", - " <object>\n", - " <integer name=\"index\" format=\"1-indexed\"/>\n", - " <string name=\"step\"/>\n", - " </object>\n", - " </list>\n", + " <list description=\"What are the ingredients for the recipe?\" name=\"ingredients\" required=\"true\">\n", + " <object required=\"true\">\n", + " <integer name=\"index\" required=\"true\"></integer>\n", + " <string format=\"is-vegan\" name=\"name\" required=\"true\"></string>\n", + " <string description=\"Suggested brand for the ingredient (if any)\" name=\"brand\" required=\"true\"></string>\n", + " <bool description=\"Is the ingredient necessary?\" name=\"optional\" required=\"true\"></bool>\n", + " <float description=\"how much of this ingredient to use\" name=\"quantity\" required=\"true\"></float>\n", + " <string name=\"units\" required=\"true\"></string>\n", + " </object>\n", + " </list>\n", + " <list description=\"What are the instructions for the recipe?\" name=\"instructions\" required=\"true\">\n", + " <object required=\"true\">\n", + " <integer name=\"index\" required=\"true\"></integer>\n", + " <string name=\"step\" required=\"true\"></string>\n", + " </object>\n", + " </list>\n", "</output>\n", "\n", - "\n", "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n", "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n", "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n", @@ -299,25 +325,24 @@ "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95minteger\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mbool\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mfloat\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95minteger\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>\u001b[0m\n", "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", "\n", - "\n", "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", @@ -337,39 +362,7 @@ } ], "source": [ - "print(guard.base_prompt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Wrap the LLM API call with `Guard`" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" - ] - } - ], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", - " max_tokens=2048,\n", - " temperature=0,\n", - " model=\"gpt-4\"\n", - ")" + "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])" ] }, { @@ -383,7 +376,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -391,73 +384,79 @@ "text/html": [ "
{\n",
        "    'ingredients': [\n",
-       "        {'index': 1, 'name': 'macaroni', 'brand': 'None', 'optional': False, 'quantity': 8.0, 'units': 'ounces'},\n",
-       "        {'index': 2, 'name': 'almond milk', 'brand': 'Silk', 'optional': False, 'quantity': 1.0, 'units': 'cup'},\n",
+       "        {\n",
+       "            'index': 1,\n",
+       "            'name': 'macaroni',\n",
+       "            'brand': 'Barilla',\n",
+       "            'optional': False,\n",
+       "            'quantity': 8.0,\n",
+       "            'units': 'ounces'\n",
+       "        },\n",
+       "        {\n",
+       "            'index': 2,\n",
+       "            'name': 'raw cashews',\n",
+       "            'brand': \"Trader Joe's\",\n",
+       "            'optional': False,\n",
+       "            'quantity': 1.0,\n",
+       "            'units': 'cup'\n",
+       "        },\n",
        "        {\n",
        "            'index': 3,\n",
        "            'name': 'nutritional yeast',\n",
-       "            'brand': 'Bragg',\n",
+       "            'brand': \"Bob's Red Mill\",\n",
        "            'optional': False,\n",
        "            'quantity': 0.25,\n",
        "            'units': 'cup'\n",
        "        },\n",
        "        {\n",
        "            'index': 4,\n",
-       "            'name': 'tahini',\n",
-       "            'brand': 'None',\n",
+       "            'name': 'garlic powder',\n",
+       "            'brand': 'McCormick',\n",
        "            'optional': False,\n",
-       "            'quantity': 2.0,\n",
-       "            'units': 'tablespoons'\n",
+       "            'quantity': 1.0,\n",
+       "            'units': 'teaspoon'\n",
        "        },\n",
        "        {\n",
        "            'index': 5,\n",
-       "            'name': 'lemon juice',\n",
-       "            'brand': 'None',\n",
+       "            'name': 'onion powder',\n",
+       "            'brand': 'McCormick',\n",
        "            'optional': False,\n",
        "            'quantity': 1.0,\n",
-       "            'units': 'tablespoon'\n",
-       "        },\n",
-       "        {\n",
-       "            'index': 6,\n",
-       "            'name': 'garlic powder',\n",
-       "            'brand': 'None',\n",
-       "            'optional': False,\n",
-       "            'quantity': 0.5,\n",
        "            'units': 'teaspoon'\n",
        "        },\n",
        "        {\n",
-       "            'index': 7,\n",
-       "            'name': 'onion powder',\n",
-       "            'brand': 'None',\n",
-       "            'optional': False,\n",
+       "            'index': 6,\n",
+       "            'name': 'turmeric',\n",
+       "            'brand': 'Simply Organic',\n",
+       "            'optional': True,\n",
        "            'quantity': 0.5,\n",
        "            'units': 'teaspoon'\n",
        "        },\n",
+       "        {'index': 7, 'name': 'salt', 'brand': 'Morton', 'optional': False, 'quantity': 1.0, 'units': 'teaspoon'},\n",
        "        {\n",
        "            'index': 8,\n",
-       "            'name': 'turmeric',\n",
-       "            'brand': 'None',\n",
+       "            'name': 'pepper',\n",
+       "            'brand': 'McCormick',\n",
        "            'optional': True,\n",
-       "            'quantity': 0.25,\n",
+       "            'quantity': 0.5,\n",
        "            'units': 'teaspoon'\n",
-       "        },\n",
-       "        {'index': 9, 'name': 'salt', 'brand': 'None', 'optional': True, 'quantity': 0.5, 'units': 'teaspoon'}\n",
+       "        }\n",
        "    ],\n",
        "    'instructions': [\n",
+       "        {'index': 1, 'step': 'Soak the cashews in water for at least 2 hours, then drain.'},\n",
        "        {\n",
-       "            'index': 1,\n",
+       "            'index': 2,\n",
        "            'step': 'Cook the macaroni according to the package instructions, then drain and set aside.'\n",
        "        },\n",
        "        {\n",
-       "            'index': 2,\n",
-       "            'step': 'In a blender, combine the almond milk, nutritional yeast, tahini, lemon juice, garlic powder, \n",
-       "onion powder, turmeric (if using), and salt (if using). Blend until smooth.'\n",
+       "            'index': 3,\n",
+       "            'step': 'In a blender, combine the soaked cashews, nutritional yeast, garlic powder, onion powder, \n",
+       "turmeric (if using), salt, and pepper. Blend until smooth.'\n",
        "        },\n",
-       "        {'index': 3, 'step': 'Pour the sauce over the cooked macaroni and stir to combine.'},\n",
+       "        {'index': 4, 'step': 'Pour the cashew sauce over the cooked macaroni and stir until well coated.'},\n",
        "        {\n",
-       "            'index': 4,\n",
-       "            'step': 'Serve the vegan mac and cheese hot, with additional nutritional yeast or other toppings if \n",
-       "desired.'\n",
+       "            'index': 5,\n",
+       "            'step': 'Serve the vegan mac and cheese hot, with extra nutritional yeast or pepper on top if desired.'\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -466,73 +465,79 @@
       "text/plain": [
        "\u001b[1m{\u001b[0m\n",
        "    \u001b[32m'ingredients'\u001b[0m: \u001b[1m[\u001b[0m\n",
-       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'name'\u001b[0m: \u001b[32m'macaroni'\u001b[0m, \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'quantity'\u001b[0m: \u001b[1;36m8.0\u001b[0m, \u001b[32m'units'\u001b[0m: \u001b[32m'ounces'\u001b[0m\u001b[1m}\u001b[0m,\n",
-       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m2\u001b[0m, \u001b[32m'name'\u001b[0m: \u001b[32m'almond milk'\u001b[0m, \u001b[32m'brand'\u001b[0m: \u001b[32m'Silk'\u001b[0m, \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'quantity'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'units'\u001b[0m: \u001b[32m'cup'\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "        \u001b[1m{\u001b[0m\n",
+       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m1\u001b[0m,\n",
+       "            \u001b[32m'name'\u001b[0m: \u001b[32m'macaroni'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'Barilla'\u001b[0m,\n",
+       "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m8.0\u001b[0m,\n",
+       "            \u001b[32m'units'\u001b[0m: \u001b[32m'ounces'\u001b[0m\n",
+       "        \u001b[1m}\u001b[0m,\n",
+       "        \u001b[1m{\u001b[0m\n",
+       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m2\u001b[0m,\n",
+       "            \u001b[32m'name'\u001b[0m: \u001b[32m'raw cashews'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m\"Trader Joe's\"\u001b[0m,\n",
+       "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n",
+       "            \u001b[32m'units'\u001b[0m: \u001b[32m'cup'\u001b[0m\n",
+       "        \u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
        "            \u001b[32m'index'\u001b[0m: \u001b[1;36m3\u001b[0m,\n",
        "            \u001b[32m'name'\u001b[0m: \u001b[32m'nutritional yeast'\u001b[0m,\n",
-       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'Bragg'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m\"Bob's Red Mill\"\u001b[0m,\n",
        "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
        "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m0.25\u001b[0m,\n",
        "            \u001b[32m'units'\u001b[0m: \u001b[32m'cup'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
        "            \u001b[32m'index'\u001b[0m: \u001b[1;36m4\u001b[0m,\n",
-       "            \u001b[32m'name'\u001b[0m: \u001b[32m'tahini'\u001b[0m,\n",
-       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m,\n",
+       "            \u001b[32m'name'\u001b[0m: \u001b[32m'garlic powder'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'McCormick'\u001b[0m,\n",
        "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
-       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m2.0\u001b[0m,\n",
-       "            \u001b[32m'units'\u001b[0m: \u001b[32m'tablespoons'\u001b[0m\n",
+       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n",
+       "            \u001b[32m'units'\u001b[0m: \u001b[32m'teaspoon'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
        "            \u001b[32m'index'\u001b[0m: \u001b[1;36m5\u001b[0m,\n",
-       "            \u001b[32m'name'\u001b[0m: \u001b[32m'lemon juice'\u001b[0m,\n",
-       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m,\n",
+       "            \u001b[32m'name'\u001b[0m: \u001b[32m'onion powder'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'McCormick'\u001b[0m,\n",
        "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
        "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n",
-       "            \u001b[32m'units'\u001b[0m: \u001b[32m'tablespoon'\u001b[0m\n",
-       "        \u001b[1m}\u001b[0m,\n",
-       "        \u001b[1m{\u001b[0m\n",
-       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m6\u001b[0m,\n",
-       "            \u001b[32m'name'\u001b[0m: \u001b[32m'garlic powder'\u001b[0m,\n",
-       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m,\n",
-       "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
-       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m0.5\u001b[0m,\n",
        "            \u001b[32m'units'\u001b[0m: \u001b[32m'teaspoon'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
-       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m7\u001b[0m,\n",
-       "            \u001b[32m'name'\u001b[0m: \u001b[32m'onion powder'\u001b[0m,\n",
-       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m,\n",
-       "            \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m6\u001b[0m,\n",
+       "            \u001b[32m'name'\u001b[0m: \u001b[32m'turmeric'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'Simply Organic'\u001b[0m,\n",
+       "            \u001b[32m'optional'\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n",
        "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m0.5\u001b[0m,\n",
        "            \u001b[32m'units'\u001b[0m: \u001b[32m'teaspoon'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m,\n",
+       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m7\u001b[0m, \u001b[32m'name'\u001b[0m: \u001b[32m'salt'\u001b[0m, \u001b[32m'brand'\u001b[0m: \u001b[32m'Morton'\u001b[0m, \u001b[32m'optional'\u001b[0m: \u001b[3;91mFalse\u001b[0m, \u001b[32m'quantity'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'units'\u001b[0m: \u001b[32m'teaspoon'\u001b[0m\u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
        "            \u001b[32m'index'\u001b[0m: \u001b[1;36m8\u001b[0m,\n",
-       "            \u001b[32m'name'\u001b[0m: \u001b[32m'turmeric'\u001b[0m,\n",
-       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m,\n",
+       "            \u001b[32m'name'\u001b[0m: \u001b[32m'pepper'\u001b[0m,\n",
+       "            \u001b[32m'brand'\u001b[0m: \u001b[32m'McCormick'\u001b[0m,\n",
        "            \u001b[32m'optional'\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n",
-       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m0.25\u001b[0m,\n",
+       "            \u001b[32m'quantity'\u001b[0m: \u001b[1;36m0.5\u001b[0m,\n",
        "            \u001b[32m'units'\u001b[0m: \u001b[32m'teaspoon'\u001b[0m\n",
-       "        \u001b[1m}\u001b[0m,\n",
-       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m9\u001b[0m, \u001b[32m'name'\u001b[0m: \u001b[32m'salt'\u001b[0m, \u001b[32m'brand'\u001b[0m: \u001b[32m'None'\u001b[0m, \u001b[32m'optional'\u001b[0m: \u001b[3;92mTrue\u001b[0m, \u001b[32m'quantity'\u001b[0m: \u001b[1;36m0.5\u001b[0m, \u001b[32m'units'\u001b[0m: \u001b[32m'teaspoon'\u001b[0m\u001b[1m}\u001b[0m\n",
+       "        \u001b[1m}\u001b[0m\n",
        "    \u001b[1m]\u001b[0m,\n",
        "    \u001b[32m'instructions'\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m1\u001b[0m, \u001b[32m'step'\u001b[0m: \u001b[32m'Soak the cashews in water for at least 2 hours, then drain.'\u001b[0m\u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
-       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m1\u001b[0m,\n",
+       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m2\u001b[0m,\n",
        "            \u001b[32m'step'\u001b[0m: \u001b[32m'Cook the macaroni according to the package instructions, then drain and set aside.'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
-       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m2\u001b[0m,\n",
-       "            \u001b[32m'step'\u001b[0m: \u001b[32m'In a blender, combine the almond milk, nutritional yeast, tahini, lemon juice, garlic powder, \u001b[0m\n",
-       "\u001b[32monion powder, turmeric \u001b[0m\u001b[32m(\u001b[0m\u001b[32mif using\u001b[0m\u001b[32m)\u001b[0m\u001b[32m, and salt \u001b[0m\u001b[32m(\u001b[0m\u001b[32mif using\u001b[0m\u001b[32m)\u001b[0m\u001b[32m. Blend until smooth.'\u001b[0m\n",
+       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m3\u001b[0m,\n",
+       "            \u001b[32m'step'\u001b[0m: \u001b[32m'In a blender, combine the soaked cashews, nutritional yeast, garlic powder, onion powder, \u001b[0m\n",
+       "\u001b[32mturmeric \u001b[0m\u001b[32m(\u001b[0m\u001b[32mif using\u001b[0m\u001b[32m)\u001b[0m\u001b[32m, salt, and pepper. Blend until smooth.'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m,\n",
-       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m3\u001b[0m, \u001b[32m'step'\u001b[0m: \u001b[32m'Pour the sauce over the cooked macaroni and stir to combine.'\u001b[0m\u001b[1m}\u001b[0m,\n",
+       "        \u001b[1m{\u001b[0m\u001b[32m'index'\u001b[0m: \u001b[1;36m4\u001b[0m, \u001b[32m'step'\u001b[0m: \u001b[32m'Pour the cashew sauce over the cooked macaroni and stir until well coated.'\u001b[0m\u001b[1m}\u001b[0m,\n",
        "        \u001b[1m{\u001b[0m\n",
-       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m4\u001b[0m,\n",
-       "            \u001b[32m'step'\u001b[0m: \u001b[32m'Serve the vegan mac and cheese hot, with additional nutritional yeast or other toppings if \u001b[0m\n",
-       "\u001b[32mdesired.'\u001b[0m\n",
+       "            \u001b[32m'index'\u001b[0m: \u001b[1;36m5\u001b[0m,\n",
+       "            \u001b[32m'step'\u001b[0m: \u001b[32m'Serve the vegan mac and cheese hot, with extra nutritional yeast or pepper on top if desired.'\u001b[0m\n",
        "        \u001b[1m}\u001b[0m\n",
        "    \u001b[1m]\u001b[0m\n",
        "\u001b[1m}\u001b[0m\n"
@@ -548,7 +553,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 55,
+   "execution_count": 10,
    "metadata": {},
    "outputs": [
     {
@@ -557,152 +562,151 @@
        "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Generate a recipe for vegan mac and cheese.                                                             │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <list name=\"ingredients\" description=\"What are the ingredients for the recipe?\">                    │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <integer name=\"index\" format=\"1-indexed\"/>                                                  │ │\n",
-       "    │ │             <string name=\"name\" format=\"is-vegan\"/>                                                     │ │\n",
-       "    │ │             <string name=\"brand\" description=\"Suggested brand for the ingredient (if any)\"/>            │ │\n",
-       "    │ │             <bool name=\"optional\" description=\"Is the ingredient necessary?\"/>                          │ │\n",
-       "    │ │             <float name=\"quantity\" description=\"how much of this ingredient to use\"                     │ │\n",
-       "    │ │ format=\"units-imperial\"/>                                                                               │ │\n",
-       "    │ │             <string name=\"units\" format=\"units-imperial\"/>                                              │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
-       "    │ │     <list name=\"instructions\" description=\"What are the instructions for the recipe?\">                  │ │\n",
-       "    │ │         <object>                                                                                        │ │\n",
-       "    │ │             <integer name=\"index\" format=\"1-indexed\"/>                                                  │ │\n",
-       "    │ │             <string name=\"step\"/>                                                                       │ │\n",
-       "    │ │         </object>                                                                                       │ │\n",
-       "    │ │     </list>                                                                                             │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ Generate a recipe for vegan mac and cheese.                                                  │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <list description=\"What are the ingredients for the recipe?\" name=\"ingredients\"            │ │ │\n",
+       "    │ │ │      │ required=\"true\">                                                                             │ │ │\n",
+       "    │ │ │      │     <object required=\"true\">                                                                 │ │ │\n",
+       "    │ │ │      │       <integer name=\"index\" required=\"true\"></integer>                                       │ │ │\n",
+       "    │ │ │      │       <string format=\"is-vegan\" name=\"name\" required=\"true\"></string>                        │ │ │\n",
+       "    │ │ │      │       <string description=\"Suggested brand for the ingredient (if any)\" name=\"brand\"         │ │ │\n",
+       "    │ │ │      │ required=\"true\"></string>                                                                    │ │ │\n",
+       "    │ │ │      │       <bool description=\"Is the ingredient necessary?\" name=\"optional\"                       │ │ │\n",
+       "    │ │ │      │ required=\"true\"></bool>                                                                      │ │ │\n",
+       "    │ │ │      │       <float description=\"how much of this ingredient to use\" name=\"quantity\"                │ │ │\n",
+       "    │ │ │      │ required=\"true\"></float>                                                                     │ │ │\n",
+       "    │ │ │      │       <string name=\"units\" required=\"true\"></string>                                         │ │ │\n",
+       "    │ │ │      │     </object>                                                                                │ │ │\n",
+       "    │ │ │      │   </list>                                                                                    │ │ │\n",
+       "    │ │ │      │   <list description=\"What are the instructions for the recipe?\" name=\"instructions\"          │ │ │\n",
+       "    │ │ │      │ required=\"true\">                                                                             │ │ │\n",
+       "    │ │ │      │     <object required=\"true\">                                                                 │ │ │\n",
+       "    │ │ │      │       <integer name=\"index\" required=\"true\"></integer>                                       │ │ │\n",
+       "    │ │ │      │       <string name=\"step\" required=\"true\"></string>                                          │ │ │\n",
+       "    │ │ │      │     </object>                                                                                │ │ │\n",
+       "    │ │ │      │   </list>                                                                                    │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
-       "    │ │     \"ingredients\": [                                                                                    │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 1,                                                                                 │ │\n",
-       "    │ │             \"name\": \"macaroni\",                                                                         │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 8.0,                                                                            │ │\n",
-       "    │ │             \"units\": \"ounces\"                                                                           │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 2,                                                                                 │ │\n",
-       "    │ │             \"name\": \"almond milk\",                                                                      │ │\n",
-       "    │ │             \"brand\": \"Silk\",                                                                            │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 1.0,                                                                            │ │\n",
-       "    │ │             \"units\": \"cup\"                                                                              │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 3,                                                                                 │ │\n",
-       "    │ │             \"name\": \"nutritional yeast\",                                                                │ │\n",
-       "    │ │             \"brand\": \"Bragg\",                                                                           │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 0.25,                                                                           │ │\n",
-       "    │ │             \"units\": \"cup\"                                                                              │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 4,                                                                                 │ │\n",
-       "    │ │             \"name\": \"tahini\",                                                                           │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 2.0,                                                                            │ │\n",
-       "    │ │             \"units\": \"tablespoons\"                                                                      │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 5,                                                                                 │ │\n",
-       "    │ │             \"name\": \"lemon juice\",                                                                      │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 1.0,                                                                            │ │\n",
-       "    │ │             \"units\": \"tablespoon\"                                                                       │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 6,                                                                                 │ │\n",
-       "    │ │             \"name\": \"garlic powder\",                                                                    │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 0.5,                                                                            │ │\n",
-       "    │ │             \"units\": \"teaspoon\"                                                                         │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 7,                                                                                 │ │\n",
-       "    │ │             \"name\": \"onion powder\",                                                                     │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": false,                                                                          │ │\n",
-       "    │ │             \"quantity\": 0.5,                                                                            │ │\n",
-       "    │ │             \"units\": \"teaspoon\"                                                                         │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 8,                                                                                 │ │\n",
-       "    │ │             \"name\": \"turmeric\",                                                                         │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": true,                                                                           │ │\n",
-       "    │ │             \"quantity\": 0.25,                                                                           │ │\n",
-       "    │ │             \"units\": \"teaspoon\"                                                                         │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 9,                                                                                 │ │\n",
-       "    │ │             \"name\": \"salt\",                                                                             │ │\n",
-       "    │ │             \"brand\": null,                                                                              │ │\n",
-       "    │ │             \"optional\": true,                                                                           │ │\n",
-       "    │ │             \"quantity\": 0.5,                                                                            │ │\n",
-       "    │ │             \"units\": \"teaspoon\"                                                                         │ │\n",
-       "    │ │         }                                                                                               │ │\n",
-       "    │ │     ],                                                                                                  │ │\n",
-       "    │ │     \"instructions\": [                                                                                   │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 1,                                                                                 │ │\n",
-       "    │ │             \"step\": \"Cook the macaroni according to the package instructions, then drain and set        │ │\n",
-       "    │ │ aside.\"                                                                                                 │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 2,                                                                                 │ │\n",
-       "    │ │             \"step\": \"In a blender, combine the almond milk, nutritional yeast, tahini, lemon juice,     │ │\n",
-       "    │ │ garlic powder, onion powder, turmeric (if using), and salt (if using). Blend until smooth.\"             │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 3,                                                                                 │ │\n",
-       "    │ │             \"step\": \"Pour the sauce over the cooked macaroni and stir to combine.\"                      │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"index\": 4,                                                                                 │ │\n",
-       "    │ │             \"step\": \"Serve the vegan mac and cheese hot, with additional nutritional yeast or other     │ │\n",
-       "    │ │ toppings if desired.\"                                                                                   │ │\n",
-       "    │ │         }                                                                                               │ │\n",
-       "    │ │     ]                                                                                                   │ │\n",
+       "    │ │   \"ingredients\": [                                                                                      │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 1,                                                                                       │ │\n",
+       "    │ │       \"name\": \"macaroni\",                                                                               │ │\n",
+       "    │ │       \"brand\": \"Barilla\",                                                                               │ │\n",
+       "    │ │       \"optional\": false,                                                                                │ │\n",
+       "    │ │       \"quantity\": 8.0,                                                                                  │ │\n",
+       "    │ │       \"units\": \"ounces\"                                                                                 │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 2,                                                                                       │ │\n",
+       "    │ │       \"name\": \"raw cashews\",                                                                            │ │\n",
+       "    │ │       \"brand\": \"Trader Joe's\",                                                                          │ │\n",
+       "    │ │       \"optional\": false,                                                                                │ │\n",
+       "    │ │       \"quantity\": 1.0,                                                                                  │ │\n",
+       "    │ │       \"units\": \"cup\"                                                                                    │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 3,                                                                                       │ │\n",
+       "    │ │       \"name\": \"nutritional yeast\",                                                                      │ │\n",
+       "    │ │       \"brand\": \"Bob's Red Mill\",                                                                        │ │\n",
+       "    │ │       \"optional\": false,                                                                                │ │\n",
+       "    │ │       \"quantity\": 0.25,                                                                                 │ │\n",
+       "    │ │       \"units\": \"cup\"                                                                                    │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 4,                                                                                       │ │\n",
+       "    │ │       \"name\": \"garlic powder\",                                                                          │ │\n",
+       "    │ │       \"brand\": \"McCormick\",                                                                             │ │\n",
+       "    │ │       \"optional\": false,                                                                                │ │\n",
+       "    │ │       \"quantity\": 1.0,                                                                                  │ │\n",
+       "    │ │       \"units\": \"teaspoon\"                                                                               │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 5,                                                                                       │ │\n",
+       "    │ │       \"name\": \"onion powder\",                                                                           │ │\n",
+       "    │ │       \"brand\": \"McCormick\",                                                                             │ │\n",
+       "    │ │       \"optional\": false,                                                                                │ │\n",
+       "    │ │       \"quantity\": 1.0,                                                                                  │ │\n",
+       "    │ │       \"units\": \"teaspoon\"                                                                               │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 6,                                                                                       │ │\n",
+       "    │ │       \"name\": \"turmeric\",                                                                               │ │\n",
+       "    │ │       \"brand\": \"Simply Organic\",                                                                        │ │\n",
+       "    │ │       \"optional\": true,                                                                                 │ │\n",
+       "    │ │       \"quantity\": 0.5,                                                                                  │ │\n",
+       "    │ │       \"units\": \"teaspoon\"                                                                               │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 7,                                                                                       │ │\n",
+       "    │ │       \"name\": \"salt\",                                                                                   │ │\n",
+       "    │ │       \"brand\": \"Morton\",                                                                                │ │\n",
+       "    │ │       \"optional\": false,                                                                                │ │\n",
+       "    │ │       \"quantity\": 1.0,                                                                                  │ │\n",
+       "    │ │       \"units\": \"teaspoon\"                                                                               │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 8,                                                                                       │ │\n",
+       "    │ │       \"name\": \"pepper\",                                                                                 │ │\n",
+       "    │ │       \"brand\": \"McCormick\",                                                                             │ │\n",
+       "    │ │       \"optional\": true,                                                                                 │ │\n",
+       "    │ │       \"quantity\": 0.5,                                                                                  │ │\n",
+       "    │ │       \"units\": \"teaspoon\"                                                                               │ │\n",
+       "    │ │     }                                                                                                   │ │\n",
+       "    │ │   ],                                                                                                    │ │\n",
+       "    │ │   \"instructions\": [                                                                                     │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 1,                                                                                       │ │\n",
+       "    │ │       \"step\": \"Soak the cashews in water for at least 2 hours, then drain.\"                             │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 2,                                                                                       │ │\n",
+       "    │ │       \"step\": \"Cook the macaroni according to the package instructions, then drain and set aside.\"      │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 3,                                                                                       │ │\n",
+       "    │ │       \"step\": \"In a blender, combine the soaked cashews, nutritional yeast, garlic powder, onion        │ │\n",
+       "    │ │ powder, turmeric (if using), salt, and pepper. Blend until smooth.\"                                     │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 4,                                                                                       │ │\n",
+       "    │ │       \"step\": \"Pour the cashew sauce over the cooked macaroni and stir until well coated.\"              │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"index\": 5,                                                                                       │ │\n",
+       "    │ │       \"step\": \"Serve the vegan mac and cheese hot, with extra nutritional yeast or pepper on top if     │ │\n",
+       "    │ │ desired.\"                                                                                               │ │\n",
+       "    │ │     }                                                                                                   │ │\n",
+       "    │ │   ]                                                                                                     │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
@@ -711,15 +715,15 @@
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 1,                                                                                 │ │\n",
        "    │ │             'name': 'macaroni',                                                                         │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
+       "    │ │             'brand': 'Barilla',                                                                         │ │\n",
        "    │ │             'optional': False,                                                                          │ │\n",
        "    │ │             'quantity': 8.0,                                                                            │ │\n",
        "    │ │             'units': 'ounces'                                                                           │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 2,                                                                                 │ │\n",
-       "    │ │             'name': 'almond milk',                                                                      │ │\n",
-       "    │ │             'brand': 'Silk',                                                                            │ │\n",
+       "    │ │             'name': 'raw cashews',                                                                      │ │\n",
+       "    │ │             'brand': \"Trader Joe's\",                                                                    │ │\n",
        "    │ │             'optional': False,                                                                          │ │\n",
        "    │ │             'quantity': 1.0,                                                                            │ │\n",
        "    │ │             'units': 'cup'                                                                              │ │\n",
@@ -727,55 +731,47 @@
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 3,                                                                                 │ │\n",
        "    │ │             'name': 'nutritional yeast',                                                                │ │\n",
-       "    │ │             'brand': 'Bragg',                                                                           │ │\n",
+       "    │ │             'brand': \"Bob's Red Mill\",                                                                  │ │\n",
        "    │ │             'optional': False,                                                                          │ │\n",
        "    │ │             'quantity': 0.25,                                                                           │ │\n",
        "    │ │             'units': 'cup'                                                                              │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 4,                                                                                 │ │\n",
-       "    │ │             'name': 'tahini',                                                                           │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
+       "    │ │             'name': 'garlic powder',                                                                    │ │\n",
+       "    │ │             'brand': 'McCormick',                                                                       │ │\n",
        "    │ │             'optional': False,                                                                          │ │\n",
-       "    │ │             'quantity': 2.0,                                                                            │ │\n",
-       "    │ │             'units': 'tablespoons'                                                                      │ │\n",
+       "    │ │             'quantity': 1.0,                                                                            │ │\n",
+       "    │ │             'units': 'teaspoon'                                                                         │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 5,                                                                                 │ │\n",
-       "    │ │             'name': 'lemon juice',                                                                      │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
+       "    │ │             'name': 'onion powder',                                                                     │ │\n",
+       "    │ │             'brand': 'McCormick',                                                                       │ │\n",
        "    │ │             'optional': False,                                                                          │ │\n",
        "    │ │             'quantity': 1.0,                                                                            │ │\n",
-       "    │ │             'units': 'tablespoon'                                                                       │ │\n",
+       "    │ │             'units': 'teaspoon'                                                                         │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 6,                                                                                 │ │\n",
-       "    │ │             'name': 'garlic powder',                                                                    │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
-       "    │ │             'optional': False,                                                                          │ │\n",
+       "    │ │             'name': 'turmeric',                                                                         │ │\n",
+       "    │ │             'brand': 'Simply Organic',                                                                  │ │\n",
+       "    │ │             'optional': True,                                                                           │ │\n",
        "    │ │             'quantity': 0.5,                                                                            │ │\n",
        "    │ │             'units': 'teaspoon'                                                                         │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 7,                                                                                 │ │\n",
-       "    │ │             'name': 'onion powder',                                                                     │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
+       "    │ │             'name': 'salt',                                                                             │ │\n",
+       "    │ │             'brand': 'Morton',                                                                          │ │\n",
        "    │ │             'optional': False,                                                                          │ │\n",
-       "    │ │             'quantity': 0.5,                                                                            │ │\n",
+       "    │ │             'quantity': 1.0,                                                                            │ │\n",
        "    │ │             'units': 'teaspoon'                                                                         │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 8,                                                                                 │ │\n",
-       "    │ │             'name': 'turmeric',                                                                         │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
-       "    │ │             'optional': True,                                                                           │ │\n",
-       "    │ │             'quantity': 0.25,                                                                           │ │\n",
-       "    │ │             'units': 'teaspoon'                                                                         │ │\n",
-       "    │ │         },                                                                                              │ │\n",
-       "    │ │         {                                                                                               │ │\n",
-       "    │ │             'index': 9,                                                                                 │ │\n",
-       "    │ │             'name': 'salt',                                                                             │ │\n",
-       "    │ │             'brand': 'None',                                                                            │ │\n",
+       "    │ │             'name': 'pepper',                                                                           │ │\n",
+       "    │ │             'brand': 'McCormick',                                                                       │ │\n",
        "    │ │             'optional': True,                                                                           │ │\n",
        "    │ │             'quantity': 0.5,                                                                            │ │\n",
        "    │ │             'units': 'teaspoon'                                                                         │ │\n",
@@ -784,22 +780,26 @@
        "    │ │     'instructions': [                                                                                   │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 1,                                                                                 │ │\n",
-       "    │ │             'step': 'Cook the macaroni according to the package instructions, then drain and set        │ │\n",
-       "    │ │ aside.'                                                                                                 │ │\n",
+       "    │ │             'step': 'Soak the cashews in water for at least 2 hours, then drain.'                       │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 2,                                                                                 │ │\n",
-       "    │ │             'step': 'In a blender, combine the almond milk, nutritional yeast, tahini, lemon juice,     │ │\n",
-       "    │ │ garlic powder, onion powder, turmeric (if using), and salt (if using). Blend until smooth.'             │ │\n",
+       "    │ │             'step': 'Cook the macaroni according to the package instructions, then drain and set        │ │\n",
+       "    │ │ aside.'                                                                                                 │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 3,                                                                                 │ │\n",
-       "    │ │             'step': 'Pour the sauce over the cooked macaroni and stir to combine.'                      │ │\n",
+       "    │ │             'step': 'In a blender, combine the soaked cashews, nutritional yeast, garlic powder, onion  │ │\n",
+       "    │ │ powder, turmeric (if using), salt, and pepper. Blend until smooth.'                                     │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
        "    │ │             'index': 4,                                                                                 │ │\n",
-       "    │ │             'step': 'Serve the vegan mac and cheese hot, with additional nutritional yeast or other     │ │\n",
-       "    │ │ toppings if desired.'                                                                                   │ │\n",
+       "    │ │             'step': 'Pour the cashew sauce over the cooked macaroni and stir until well coated.'        │ │\n",
+       "    │ │         },                                                                                              │ │\n",
+       "    │ │         {                                                                                               │ │\n",
+       "    │ │             'index': 5,                                                                                 │ │\n",
+       "    │ │             'step': 'Serve the vegan mac and cheese hot, with extra nutritional yeast or pepper on top  │ │\n",
+       "    │ │ if desired.'                                                                                            │ │\n",
        "    │ │         }                                                                                               │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
@@ -811,152 +811,151 @@
        "Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGenerate a recipe for vegan mac and cheese.\u001b[0m\u001b[48;2;240;248;255m                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGenerate a recipe for vegan mac and cheese.                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                             \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                          \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                               \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`.                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"ingredients\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 1,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"macaroni\",\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 8.0,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"ounces\"\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 2,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"almond milk\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": \"Silk\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 1.0,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"cup\"\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 3,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"nutritional yeast\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": \"Bragg\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 0.25,\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"cup\"\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 4,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"tahini\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 2.0,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"tablespoons\"\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 5,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"lemon juice\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 1.0,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"tablespoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 6,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"garlic powder\",\u001b[0m\u001b[48;2;245;245;220m                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 0.5,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 7,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"onion powder\",\u001b[0m\u001b[48;2;245;245;220m                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 0.5,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 8,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"turmeric\",\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": true,\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 0.25,\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 9,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"name\": \"salt\",\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"brand\": null,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"optional\": true,\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"quantity\": 0.5,\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                        \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"instructions\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 1,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"step\": \"Cook the macaroni according to the package instructions, then drain and set \u001b[0m\u001b[48;2;245;245;220m      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220maside.\"\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 2,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"step\": \"In a blender, combine the almond milk, nutritional yeast, tahini, lemon juice, \u001b[0m\u001b[48;2;245;245;220m   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgarlic powder, onion powder, turmeric (if using), and salt (if using). Blend until smooth.\"\u001b[0m\u001b[48;2;245;245;220m            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 3,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"step\": \"Pour the sauce over the cooked macaroni and stir to combine.\"\u001b[0m\u001b[48;2;245;245;220m                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"index\": 4,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m            \"step\": \"Serve the vegan mac and cheese hot, with additional nutritional yeast or other \u001b[0m\u001b[48;2;245;245;220m   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mtoppings if desired.\"\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        }\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"ingredients\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 1,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"macaroni\",\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"Barilla\",\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 8.0,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"ounces\"\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 2,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"raw cashews\",\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"Trader Joe's\",\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 1.0,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"cup\"\u001b[0m\u001b[48;2;245;245;220m                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 3,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"nutritional yeast\",\u001b[0m\u001b[48;2;245;245;220m                                                                     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"Bob's Red Mill\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 0.25,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"cup\"\u001b[0m\u001b[48;2;245;245;220m                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 4,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"garlic powder\",\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"McCormick\",\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 1.0,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 5,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"onion powder\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"McCormick\",\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 1.0,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 6,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"turmeric\",\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"Simply Organic\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": true,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 0.5,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 7,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"salt\",\u001b[0m\u001b[48;2;245;245;220m                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"Morton\",\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": false,\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 1.0,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 8,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"name\": \"pepper\",\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"brand\": \"McCormick\",\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"optional\": true,\u001b[0m\u001b[48;2;245;245;220m                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"quantity\": 0.5,\u001b[0m\u001b[48;2;245;245;220m                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"units\": \"teaspoon\"\u001b[0m\u001b[48;2;245;245;220m                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ],\u001b[0m\u001b[48;2;245;245;220m                                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"instructions\": [\u001b[0m\u001b[48;2;245;245;220m                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 1,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"step\": \"Soak the cashews in water for at least 2 hours, then drain.\"\u001b[0m\u001b[48;2;245;245;220m                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 2,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"step\": \"Cook the macaroni according to the package instructions, then drain and set aside.\"\u001b[0m\u001b[48;2;245;245;220m     \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 3,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"step\": \"In a blender, combine the soaked cashews, nutritional yeast, garlic powder, onion \u001b[0m\u001b[48;2;245;245;220m      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mpowder, turmeric (if using), salt, and pepper. Blend until smooth.\"\u001b[0m\u001b[48;2;245;245;220m                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 4,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"step\": \"Pour the cashew sauce over the cooked macaroni and stir until well coated.\"\u001b[0m\u001b[48;2;245;245;220m             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    },\u001b[0m\u001b[48;2;245;245;220m                                                                                                 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    {\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"index\": 5,\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m      \"step\": \"Serve the vegan mac and cheese hot, with extra nutritional yeast or pepper on top if \u001b[0m\u001b[48;2;245;245;220m   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mdesired.\"\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    }\u001b[0m\u001b[48;2;245;245;220m                                                                                                  \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  ]\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
@@ -965,15 +964,15 @@
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 1,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'macaroni',\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'Barilla',\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 8.0,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'ounces'\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 2,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'almond milk',\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'Silk',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'raw cashews',\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': \"Trader Joe's\",\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 1.0,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'cup'\u001b[0m\u001b[48;2;240;255;240m                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -981,55 +980,47 @@
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 3,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'nutritional yeast',\u001b[0m\u001b[48;2;240;255;240m                                                               \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'Bragg',\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': \"Bob's Red Mill\",\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 0.25,\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'cup'\u001b[0m\u001b[48;2;240;255;240m                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 4,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'tahini',\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'garlic powder',\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'McCormick',\u001b[0m\u001b[48;2;240;255;240m                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 2.0,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'tablespoons'\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 1.0,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'teaspoon'\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 5,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'lemon juice',\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'onion powder',\u001b[0m\u001b[48;2;240;255;240m                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'McCormick',\u001b[0m\u001b[48;2;240;255;240m                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 1.0,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'tablespoon'\u001b[0m\u001b[48;2;240;255;240m                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'teaspoon'\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 6,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'garlic powder',\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'turmeric',\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'Simply Organic',\u001b[0m\u001b[48;2;240;255;240m                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': True,\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 0.5,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'teaspoon'\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 7,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'onion powder',\u001b[0m\u001b[48;2;240;255;240m                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'salt',\u001b[0m\u001b[48;2;240;255;240m                                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'Morton',\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': False,\u001b[0m\u001b[48;2;240;255;240m                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 0.5,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 1.0,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'teaspoon'\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 8,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'turmeric',\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': True,\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 0.25,\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'teaspoon'\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 9,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'salt',\u001b[0m\u001b[48;2;240;255;240m                                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'None',\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'name': 'pepper',\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'brand': 'McCormick',\u001b[0m\u001b[48;2;240;255;240m                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'optional': True,\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'quantity': 0.5,\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'units': 'teaspoon'\u001b[0m\u001b[48;2;240;255;240m                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1038,22 +1029,26 @@
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'instructions': [\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 1,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Cook the macaroni according to the package instructions, then drain and set \u001b[0m\u001b[48;2;240;255;240m      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240maside.'\u001b[0m\u001b[48;2;240;255;240m                                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Soak the cashews in water for at least 2 hours, then drain.'\u001b[0m\u001b[48;2;240;255;240m                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 2,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'In a blender, combine the almond milk, nutritional yeast, tahini, lemon juice, \u001b[0m\u001b[48;2;240;255;240m   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mgarlic powder, onion powder, turmeric (if using), and salt (if using). Blend until smooth.'\u001b[0m\u001b[48;2;240;255;240m            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Cook the macaroni according to the package instructions, then drain and set \u001b[0m\u001b[48;2;240;255;240m      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240maside.'\u001b[0m\u001b[48;2;240;255;240m                                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 3,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Pour the sauce over the cooked macaroni and stir to combine.'\u001b[0m\u001b[48;2;240;255;240m                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'In a blender, combine the soaked cashews, nutritional yeast, garlic powder, onion \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mpowder, turmeric (if using), salt, and pepper. Blend until smooth.'\u001b[0m\u001b[48;2;240;255;240m                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 4,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Serve the vegan mac and cheese hot, with additional nutritional yeast or other \u001b[0m\u001b[48;2;240;255;240m   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtoppings if desired.'\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Pour the cashew sauce over the cooked macaroni and stir until well coated.'\u001b[0m\u001b[48;2;240;255;240m       \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        },\u001b[0m\u001b[48;2;240;255;240m                                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        {\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'index': 5,\u001b[0m\u001b[48;2;240;255;240m                                                                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            'step': 'Serve the vegan mac and cheese hot, with extra nutritional yeast or pepper on top \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mif desired.'\u001b[0m\u001b[48;2;240;255;240m                                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        }\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -1086,7 +1081,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.17"
+   "version": "3.12.1"
   },
   "orig_nbformat": 4,
   "vscode": {
diff --git a/docs/examples/regex_validation.ipynb b/docs/examples/regex_validation.ipynb
index 3d9f948d7..4b5c598bb 100644
--- a/docs/examples/regex_validation.ipynb
+++ b/docs/examples/regex_validation.ipynb
@@ -2,11 +2,22 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 1,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mregex_match...\u001b[0m\n",
+      "✅Successfully installed guardrails/regex_match!\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
    "source": [
-    "!guardrails hub install hub://guardrails/regex_match"
+    "!guardrails hub install hub://guardrails/regex_match --quiet"
    ]
   },
   {
@@ -29,7 +40,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 2,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -45,14 +56,17 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 3,
    "metadata": {},
    "outputs": [],
    "source": [
-    "import openai\n",
     "from guardrails import Guard\n",
     "from guardrails.hub import RegexMatch\n",
-    "from rich import print"
+    "from rich import print\n",
+    "\n",
+    "# Set your OPENAI_API_KEY as an environment variable\n",
+    "# import os\n",
+    "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\""
    ]
   },
   {
@@ -66,58 +80,131 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 21,
    "metadata": {},
    "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
-     ]
-    },
     {
      "data": {
       "text/html": [
        "
Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "│   │ │ I am writing a movie and need a fake phone number. Generate a fake phone number. Do not write anything  │ │\n",
+       "│   │ │ other than the phone number.                                                                            │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "│   │ │ No message history.                                                                                     │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "│   │ │ (555) 012-3456                                                                                          │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "│   │ │ FieldReAsk(                                                                                             │ │\n",
+       "│   │ │     incorrect_value='(555) 012-3456',                                                                   │ │\n",
+       "│   │ │     fail_results=[                                                                                      │ │\n",
+       "│   │ │         FailResult(                                                                                     │ │\n",
+       "│   │ │             outcome='fail',                                                                             │ │\n",
+       "│   │ │             error_message='Result must match \\\\d{3}-\\\\d{3}-\\\\d{4}',                                     │ │\n",
+       "│   │ │             fix_value='ah300-632-4603ah',                                                               │ │\n",
+       "│   │ │             error_spans=None,                                                                           │ │\n",
+       "│   │ │             metadata=None,                                                                              │ │\n",
+       "│   │ │             validated_chunk=None                                                                        │ │\n",
+       "│   │ │         )                                                                                               │ │\n",
+       "│   │ │     ],                                                                                                  │ │\n",
+       "│   │ │     additional_properties={},                                                                           │ │\n",
+       "│   │ │     path=None                                                                                           │ │\n",
+       "│   │ │ )                                                                                                       │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │ I am writing a movie and need a fake phone number. Generate a fake phone number. Do not write anything  │ │\n",
-       "    │ │ other than the phone number.                                                                            │ │\n",
+       "    │ │ This was a previous response you generated:                                                             │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ======                                                                                                  │ │\n",
+       "    │ │ (555) 012-3456                                                                                          │ │\n",
+       "    │ │ ======                                                                                                  │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Generate a new response that corrects your old response such that the following issues are fixed        │ │\n",
+       "    │ │ - Result must match \\d{3}-\\d{3}-\\d{4}                                                                   │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Your generated response should satisfy the following properties:                                        │ │\n",
+       "    │ │ - guardrails/regex_match: regex=\\d{3}-\\d{3}-\\d{4} match_type=search                                     │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Don't talk; just go.                                                                                    │ │\n",
+       "    │ │                                                                                                         │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, expressing yourself through a string.                                      │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
        "    │ │ No message history.                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ Sure! Here's a fake phone number for your movie: 555-123-4567.                                          │ │\n",
+       "    │ │ 555-012-3456                                                                                            │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ \"Sure! Here's a fake phone number for your movie: 555-123-4567.\"                                        │ │\n",
+       "    │ │ '555-012-3456'                                                                                          │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
        "
\n" ], "text/plain": [ "Logs\n", - "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + "│ │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mI am writing a movie and need a fake phone number. Generate a fake phone number. Do not write anything \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mother than the phone number.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m(555) 012-3456\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mFieldReAsk(\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m incorrect_value='(555) 012-3456',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m fail_results=[\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m FailResult(\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m outcome='fail',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m error_message='Result must match \\\\d{3}-\\\\d{3}-\\\\d{4}',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m fix_value='ah300-632-4603ah',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m error_spans=None,\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m metadata=None,\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m validated_chunk=None\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m )\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m ],\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m additional_properties={},\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m path=None\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m)\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n", + "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n", " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mI am writing a movie and need a fake phone number. Generate a fake phone number. Do not write anything \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mother than the phone number.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mThis was a previous response you generated:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m======\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m(555) 012-3456\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m======\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGenerate a new response that corrects your old response such that the following issues are fixed\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- Result must match \\d{3}-\\d{3}-\\d{4}\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYour generated response should satisfy the following properties:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- guardrails/regex_match: regex=\\d{3}-\\d{3}-\\d{4} match_type=search\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mDon't talk; just go.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, expressing yourself through a string.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mSure! Here's a fake phone number for your movie: 555-123-4567.\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m555-012-3456\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m\"Sure! Here's a fake phone number for your movie: 555-123-4567.\"\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m'555-012-3456'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] @@ -133,7 +220,7 @@ "\n", "guard(\n", " prompt='I am writing a movie and need a fake phone number. Generate a fake phone number. Do not write anything other than the phone number.',\n", - " llm_api=openai.chat.completions.create\n", + " model=\"gpt-4-turbo\",\n", ")\n", "\n", "print(guard.history.last.tree)" @@ -156,7 +243,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.17" + "version": "3.12.1" }, "orig_nbformat": 4 }, diff --git a/docs/examples/response_is_on_topic.ipynb b/docs/examples/response_is_on_topic.ipynb index 58692a146..2432c508d 100644 --- a/docs/examples/response_is_on_topic.ipynb +++ b/docs/examples/response_is_on_topic.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "metadata": {}, "outputs": [ { @@ -10,25 +10,15 @@ "output_type": "stream", "text": [ "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/tryolabs/\u001b[0m\u001b[95mrestricttotopic...\u001b[0m\n", - "\u001b[2K\u001b[32m[ ===]\u001b[0m Fetching manifestst\n", - "\u001b[2K\u001b[32m[== ]\u001b[0m Downloading dependencies Running command git clone --filter=blob:none --quiet https://github.com/tryolabs/restricttotopic.git /private/var/folders/w2/ssf16z690zd7_4dggw0y5s_m0000gn/T/pip-req-build-advwvzw9\n", - "\u001b[2K\u001b[32m[=== ]\u001b[0m Downloading dependencies\n", - "\u001b[1A\u001b[2K\u001b[?25l\u001b[32m[ ]\u001b[0m Running post-install setup\n", - "\u001b[1A\u001b[2K✅Successfully installed tryolabs/restricttotopic!\n", - "\n", + "✅Successfully installed tryolabs/restricttotopic!\n", "\n", - "\u001b[1mImport validator:\u001b[0m\n", - "from guardrails.hub import RestrictToTopic\n", - "\n", - "\u001b[1mGet more info:\u001b[0m\n", - "\u001b[4;94mhttps://hub.guardrailsai.com/validator/tryolabs/restricttotopic\u001b[0m\n", "\n" ] } ], "source": [ "\n", - "!guardrails hub install hub://tryolabs/restricttotopic" + "!guardrails hub install hub://tryolabs/restricttotopic --quiet" ] }, { @@ -68,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -85,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -107,7 +97,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -146,14 +136,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Validation failed for field with errors: Invalid topics found: ['tablet', 'computer', 'phone']\n" + "Validation failed for field with errors: Invalid topics found: ['tablet', 'phone', 'computer']\n" ] } ], @@ -197,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -243,14 +233,14 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Validation failed for field with errors: Invalid topics found: ['tablet']\n" + "Validation failed for field with errors: Invalid topics found: ['tablet', 'phone']\n" ] } ], @@ -295,7 +285,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/docs/examples/secrets_detection.ipynb b/docs/examples/secrets_detection.ipynb index 3be7b0905..738ea8a18 100644 --- a/docs/examples/secrets_detection.ipynb +++ b/docs/examples/secrets_detection.ipynb @@ -2,11 +2,22 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95msecrets_present...\u001b[0m\n", + "✅Successfully installed guardrails/secrets_present!\n", + "\n", + "\n" + ] + } + ], "source": [ - "!guardrails hub install hub://guardrails/secrets_present" + "!guardrails hub install hub://guardrails/secrets_present --quiet" ] }, { @@ -22,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -30,7 +41,7 @@ "output_type": "stream", "text": [ "\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.1\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" ] } @@ -42,18 +53,9 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/zayd/workspace/guardrails/.venv/lib/python3.9/site-packages/torch/cuda/__init__.py:611: UserWarning: Can't initialize NVML\n", - " warnings.warn(\"Can't initialize NVML\")\n" - ] - } - ], + "outputs": [], "source": [ "# Import the guardrails package\n", "# and import the SecretsPresent validator\n", @@ -65,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -81,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -154,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -237,7 +239,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.17" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/docs/examples/select_choice_based_on_action.ipynb b/docs/examples/select_choice_based_on_action.ipynb index a26124879..17a106318 100644 --- a/docs/examples/select_choice_based_on_action.ipynb +++ b/docs/examples/select_choice_based_on_action.ipynb @@ -2,11 +2,22 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mvalid_choices...\u001b[0m\n", + "✅Successfully installed guardrails/valid_choices!\n", + "\n", + "\n" + ] + } + ], "source": [ - "!guardrails hub install hub://guardrails/valid_choices" + "!guardrails hub install hub://guardrails/valid_choices --quiet" ] }, { @@ -43,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-08-23T15:09:26.331177Z", @@ -72,7 +83,7 @@ "\n", "You run into a ${opp_type}. What do you do?\n", "\n", - "${gr.complete_json_suffix_v2}\n", + "${gr.complete_xml_suffix_v2}\n", "\n", "\n", "\"\"\"" @@ -87,9 +98,18 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", + " from tqdm.autonotebook import tqdm, trange\n" + ] + } + ], "source": [ "from guardrails.hub import ValidChoices\n", "from pydantic import BaseModel, Field\n", @@ -100,7 +120,7 @@ "\n", "You run into a ${opp_type}. What do you do?\n", "\n", - "${gr.complete_json_suffix_v2}\"\"\"\n", + "${gr.complete_xml_suffix_v2}\"\"\"\n", "\n", "class Fight(BaseModel):\n", " chosen_action: Literal['fight']\n", @@ -138,7 +158,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-08-23T15:09:28.590929Z", @@ -163,7 +183,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -171,19 +191,100 @@ "\n", "from rich import print\n", "\n", - "guard = gd.Guard.from_pydantic(output_class=FightOrFlight, prompt=prompt)" + "guard = gd.Guard.from_pydantic(output_class=FightOrFlight)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `Guard` object compiles the output schema and adds it to the prompt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Wrap the LLM API call with `Guard`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The `Guard` object compiles the output schema and adds it to the prompt. We can see the final prompt below:" + "We can now wrap the LLM API call with the `Guard` object. This will ensure that the LLM generates an output that is compliant with the RAIL spec.\n", + "\n", + "To start, we test with a 'giant' as an opponent, and look at the output." ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2023-08-23T15:10:08.998121Z", + "start_time": "2023-08-23T15:10:08.792027Z" + } + }, + "outputs": [], + "source": [ + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "raw_llm_response, validated_response, *rest = guard(\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={'opp_type': 'giant'},\n", + " model=\"gpt-4o\",\n", + " max_tokens=256,\n", + " temperature=0.0,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Running the cell above returns:\n", + "1. The raw LLM text output as a single string.\n", + "2. A dictionary where the key is `python_code` and the value is the generated code.\n", + "\n", + "We can see that if the LLM chooses `flight`, the output is a dictionary with `flight_direction` and `distance` fields." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{'action': {'chosen_action': 'flight', 'flight_direction': 'north', 'distance': 3}}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\u001b[32m'action'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'chosen_action'\u001b[0m: \u001b[32m'flight'\u001b[0m, \u001b[32m'flight_direction'\u001b[0m: \u001b[32m'north'\u001b[0m, \u001b[32m'distance'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(validated_response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also see the final prompt below:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-08-23T15:09:32.364711Z", @@ -198,24 +299,25 @@ "You are a human in an enchanted forest. You come across opponents of different types, and you should fight smaller \n", "opponents and run away from bigger ones.\n", "\n", - "You run into a ${opp_type}. What do you do?\n", + "You run into a giant. What do you do?\n", "\n", "\n", "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "<output>\n", - " <choice name=\"action\" discriminator=\"chosen_action\">\n", - " <case name=\"fight\">\n", - " <string name=\"weapon\" format=\"valid-choices: choices=['crossbow', 'machine gun']\"/>\n", - " </case>\n", - " <case name=\"flight\">\n", - " <string name=\"flight_direction\" format=\"valid-choices: choices=['north', 'south', 'east', 'west']\"/>\n", - " <integer name=\"distance\" format=\"valid-choices: choices=[1, 2, 3, 4]\"/>\n", - " </case>\n", - " </choice>\n", + " <choice discriminator=\"chosen_action\" name=\"action\" required=\"true\">\n", + " <case name=\"fight\">\n", + " <string format=\"guardrails/valid_choices: ['crossbow', 'machine gun']\" name=\"weapon\" \n", + "required=\"true\"></string>\n", + " </case>\n", + " <case name=\"flight\">\n", + " <string format=\"guardrails/valid_choices: ['north', 'south', 'east', 'west']\" name=\"flight_direction\" \n", + "required=\"true\"></string>\n", + " <integer format=\"guardrails/valid_choices: [1, 2, 3, 4]\" name=\"distance\" required=\"true\"></integer>\n", + " </case>\n", + " </choice>\n", "</output>\n", "\n", - "\n", "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n", "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n", "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n", @@ -234,24 +336,25 @@ "You are a human in an enchanted forest. You come across opponents of different types, and you should fight smaller \n", "opponents and run away from bigger ones.\n", "\n", - "You run into a $\u001b[1m{\u001b[0mopp_type\u001b[1m}\u001b[0m. What do you do?\n", + "You run into a giant. What do you do?\n", "\n", "\n", "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mcase\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mcase\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mchoice\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mcase\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95minteger\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mcase\u001b[0m\u001b[39m>\u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mchoice\u001b[0m\u001b[39m>\u001b[0m\n", "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", "\n", - "\n", "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", @@ -270,93 +373,7 @@ } ], "source": [ - "print(guard.base_prompt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Wrap the LLM API call with `Guard`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can now wrap the LLM API call with the `Guard` object. This will ensure that the LLM generates an output that is compliant with the RAIL spec.\n", - "\n", - "To start, we test with a 'giant' as an opponent, and look at the output." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "ExecuteTime": { - "end_time": "2023-08-23T15:10:08.998121Z", - "start_time": "2023-08-23T15:10:08.792027Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" - ] - } - ], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", - " prompt_params={'opp_type': 'giant'},\n", - " model=\"gpt-3.5-turbo\",\n", - " max_tokens=256,\n", - " temperature=0.0,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Running the cell above returns:\n", - "1. The raw LLM text output as a single string.\n", - "2. A dictionary where the key is `python_code` and the value is the generated code.\n", - "\n", - "We can see that if the LLM chooses `flight`, the output is a dictionary with `flight_direction` and `distance` fields." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
{'action': {'chosen_action': 'flight', 'flight_direction': 'north', 'distance': 1}}\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m{\u001b[0m\u001b[32m'action'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'chosen_action'\u001b[0m: \u001b[32m'flight'\u001b[0m, \u001b[32m'flight_direction'\u001b[0m: \u001b[32m'north'\u001b[0m, \u001b[32m'distance'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "print(validated_response)" + "print(guard.history.last.iterations.first.inputs.msg_history[0][\"content\"])" ] }, { @@ -368,74 +385,184 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "│   │ │ No prompt                                                                                               │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "│   │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "│   │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "│   │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "│   │ │ │ user │                                                                                              │ │ │\n",
+       "│   │ │ │      │ You are a human in an enchanted forest. You come across opponents of different types, and    │ │ │\n",
+       "│   │ │ │      │ you should fight smaller opponents and run away from bigger ones.                            │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ You run into a giant. What do you do?                                                        │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "│   │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ <output>                                                                                     │ │ │\n",
+       "│   │ │ │      │   <choice discriminator=\"chosen_action\" name=\"action\" required=\"true\">                       │ │ │\n",
+       "│   │ │ │      │     <case name=\"fight\">                                                                      │ │ │\n",
+       "│   │ │ │      │       <string format=\"guardrails/valid_choices: ['crossbow', 'machine gun']\" name=\"weapon\"   │ │ │\n",
+       "│   │ │ │      │ required=\"true\"></string>                                                                    │ │ │\n",
+       "│   │ │ │      │     </case>                                                                                  │ │ │\n",
+       "│   │ │ │      │     <case name=\"flight\">                                                                     │ │ │\n",
+       "│   │ │ │      │       <string format=\"guardrails/valid_choices: ['north', 'south', 'east', 'west']\"          │ │ │\n",
+       "│   │ │ │      │ name=\"flight_direction\" required=\"true\"></string>                                            │ │ │\n",
+       "│   │ │ │      │       <integer format=\"guardrails/valid_choices: [1, 2, 3, 4]\" name=\"distance\"               │ │ │\n",
+       "│   │ │ │      │ required=\"true\"></integer>                                                                   │ │ │\n",
+       "│   │ │ │      │     </case>                                                                                  │ │ │\n",
+       "│   │ │ │      │   </choice>                                                                                  │ │ │\n",
+       "│   │ │ │      │ </output>                                                                                    │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "│   │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "│   │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "│   │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "│   │ │ │      │ correct and concise.                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "│   │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "│   │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "│   │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "│   │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "│   │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "│   │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "│   │ │ ```json                                                                                                 │ │\n",
+       "│   │ │ {                                                                                                       │ │\n",
+       "│   │ │   \"action\": {                                                                                           │ │\n",
+       "│   │ │     \"flight_direction\": \"north\",                                                                        │ │\n",
+       "│   │ │     \"distance\": 3                                                                                       │ │\n",
+       "│   │ │   },                                                                                                    │ │\n",
+       "│   │ │   \"chosen_action\": \"flight\"                                                                             │ │\n",
+       "│   │ │ }                                                                                                       │ │\n",
+       "│   │ │ ```                                                                                                     │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "│   │ │ SkeletonReAsk(                                                                                          │ │\n",
+       "│   │ │     incorrect_value={'action': {'flight_direction': 'north', 'distance': 3}},                           │ │\n",
+       "│   │ │     fail_results=[                                                                                      │ │\n",
+       "│   │ │         FailResult(                                                                                     │ │\n",
+       "│   │ │             outcome='fail',                                                                             │ │\n",
+       "│   │ │             error_message='JSON does not match schema:\\n{\\n  \"$.action\": [\\n    \"{\\'flight_direction\\': │ │\n",
+       "│   │ │ \\'north\\', \\'distance\\': 3} is not valid under any of the given schemas\"\\n  ]\\n}',                      │ │\n",
+       "│   │ │             fix_value=None,                                                                             │ │\n",
+       "│   │ │             error_spans=None,                                                                           │ │\n",
+       "│   │ │             metadata=None,                                                                              │ │\n",
+       "│   │ │             validated_chunk=None                                                                        │ │\n",
+       "│   │ │         )                                                                                               │ │\n",
+       "│   │ │     ],                                                                                                  │ │\n",
+       "│   │ │     additional_properties={}                                                                            │ │\n",
+       "│   │ │ )                                                                                                       │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │ You are a human in an enchanted forest. You come across opponents of different types, and you should    │ │\n",
-       "    │ │ fight smaller opponents and run away from bigger ones.                                                  │ │\n",
+       "    │ │ I was given the following JSON response, which had problems due to incorrect values.                    │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │ You run into a giant. What do you do?                                                                   │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"incorrect_value\": {                                                                                  │ │\n",
+       "    │ │     \"action\": {                                                                                         │ │\n",
+       "    │ │       \"flight_direction\": \"north\",                                                                      │ │\n",
+       "    │ │       \"distance\": 3                                                                                     │ │\n",
+       "    │ │     }                                                                                                   │ │\n",
+       "    │ │   },                                                                                                    │ │\n",
+       "    │ │   \"error_messages\": [                                                                                   │ │\n",
+       "    │ │     \"JSON does not match schema:\\n{\\n  \\\"$.action\\\": [\\n    \\\"{'flight_direction': 'north', 'distance': │ │\n",
+       "    │ │ 3} is not valid under any of the given schemas\\\"\\n  ]\\n}\"                                               │ │\n",
+       "    │ │   ]                                                                                                     │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Help me correct the incorrect values based on the given error messages.                                 │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
        "    │ │ it into.                                                                                                │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <choice name=\"action\" discriminator=\"chosen_action\">                                                │ │\n",
-       "    │ │         <case name=\"fight\">                                                                             │ │\n",
-       "    │ │             <string name=\"weapon\" format=\"valid-choices: choices=['crossbow', 'machine gun']\"/>         │ │\n",
-       "    │ │         </case>                                                                                         │ │\n",
-       "    │ │         <case name=\"flight\">                                                                            │ │\n",
-       "    │ │             <string name=\"flight_direction\" format=\"valid-choices: choices=['north', 'south', 'east',   │ │\n",
-       "    │ │ 'west']\"/>                                                                                              │ │\n",
-       "    │ │             <integer name=\"distance\" format=\"valid-choices: choices=[1, 2, 3, 4]\"/>                     │ │\n",
-       "    │ │         </case>                                                                                         │ │\n",
-       "    │ │     </choice>                                                                                           │ │\n",
+       "    │ │   <choice discriminator=\"chosen_action\" name=\"action\" required=\"true\">                                  │ │\n",
+       "    │ │     <case name=\"fight\">                                                                                 │ │\n",
+       "    │ │       <string format=\"guardrails/valid_choices: ['crossbow', 'machine gun']\" name=\"weapon\"              │ │\n",
+       "    │ │ required=\"true\"></string>                                                                               │ │\n",
+       "    │ │     </case>                                                                                             │ │\n",
+       "    │ │     <case name=\"flight\">                                                                                │ │\n",
+       "    │ │       <string format=\"guardrails/valid_choices: ['north', 'south', 'east', 'west']\"                     │ │\n",
+       "    │ │ name=\"flight_direction\" required=\"true\"></string>                                                       │ │\n",
+       "    │ │       <integer format=\"guardrails/valid_choices: [1, 2, 3, 4]\" name=\"distance\"                          │ │\n",
+       "    │ │ required=\"true\"></integer>                                                                              │ │\n",
+       "    │ │     </case>                                                                                             │ │\n",
+       "    │ │   </choice>                                                                                             │ │\n",
        "    │ │ </output>                                                                                               │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
        "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
        "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
        "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise.                                 │ │\n",
+       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
+       "    │ │ enter `null`.                                                                                           │ │\n",
        "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "    │ │ Here's an example of the structure:                                                                     │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"action\": {                                                                                           │ │\n",
+       "    │ │     \"chosen_action\": \"flight\",                                                                          │ │\n",
+       "    │ │     \"flight_direction\": \"few\",                                                                          │ │\n",
+       "    │ │     \"distance\": 10                                                                                      │ │\n",
+       "    │ │   }                                                                                                     │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
        "    │ │                                                                                                         │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ You are a helpful assistant only capable of communicating with valid JSON, and no other text.           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
+       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
+       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
+       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
+       "    │ │ enter `null`.                                                                                           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
+       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "    │ │ etc.]}`                                                                                                 │ │\n",
+       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "    │ │                                                                                                         │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
        "    │ │ No message history.                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ ```json                                                                                                 │ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │   \"action\": {                                                                                           │ │\n",
        "    │ │     \"chosen_action\": \"flight\",                                                                          │ │\n",
        "    │ │     \"flight_direction\": \"north\",                                                                        │ │\n",
-       "    │ │     \"distance\": 1                                                                                       │ │\n",
+       "    │ │     \"distance\": 3                                                                                       │ │\n",
        "    │ │   }                                                                                                     │ │\n",
        "    │ │ }                                                                                                       │ │\n",
+       "    │ │ ```                                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     'action': {                                                                                         │ │\n",
        "    │ │         'chosen_action': 'flight',                                                                      │ │\n",
        "    │ │         'flight_direction': 'north',                                                                    │ │\n",
-       "    │ │         'distance': 1                                                                                   │ │\n",
+       "    │ │         'distance': 3                                                                                   │ │\n",
        "    │ │     }                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
@@ -444,67 +571,177 @@
       ],
       "text/plain": [
        "Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "│   │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mYou are a human in an enchanted forest. You come across opponents of different types, and   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myou should fight smaller opponents and run away from bigger ones.                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mYou run into a giant. What do you do?                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise.                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"action\": {\u001b[0m\u001b[48;2;245;245;220m                                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"flight_direction\": \"north\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"distance\": 3\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  },\u001b[0m\u001b[48;2;245;245;220m                                                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"chosen_action\": \"flight\"\u001b[0m\u001b[48;2;245;245;220m                                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mSkeletonReAsk(\u001b[0m\u001b[48;2;240;255;240m                                                                                         \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    incorrect_value={'action': {'flight_direction': 'north', 'distance': 3}},\u001b[0m\u001b[48;2;240;255;240m                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    fail_results=[\u001b[0m\u001b[48;2;240;255;240m                                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        FailResult(\u001b[0m\u001b[48;2;240;255;240m                                                                                    \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            outcome='fail',\u001b[0m\u001b[48;2;240;255;240m                                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            error_message='JSON does not match schema:\\n{\\n  \"$.action\": [\\n    \"{\\'flight_direction\\':\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m\\'north\\', \\'distance\\': 3} is not valid under any of the given schemas\"\\n  ]\\n}',\u001b[0m\u001b[48;2;240;255;240m                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            fix_value=None,\u001b[0m\u001b[48;2;240;255;240m                                                                            \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            error_spans=None,\u001b[0m\u001b[48;2;240;255;240m                                                                          \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            metadata=None,\u001b[0m\u001b[48;2;240;255;240m                                                                             \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m            validated_chunk=None\u001b[0m\u001b[48;2;240;255;240m                                                                       \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        )\u001b[0m\u001b[48;2;240;255;240m                                                                                              \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    ],\u001b[0m\u001b[48;2;240;255;240m                                                                                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    additional_properties={}\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m)\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "│   │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
+       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
        "    │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYou are a human in an enchanted forest. You come across opponents of different types, and you should \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mfight smaller opponents and run away from bigger ones.\u001b[0m\u001b[48;2;240;248;255m                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mI was given the following JSON response, which had problems due to incorrect values.\u001b[0m\u001b[48;2;240;248;255m                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \"incorrect_value\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \"action\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"flight_direction\": \"north\",\u001b[0m\u001b[48;2;240;248;255m                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \"distance\": 3\u001b[0m\u001b[48;2;240;248;255m                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    }\u001b[0m\u001b[48;2;240;248;255m                                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  },\u001b[0m\u001b[48;2;240;248;255m                                                                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \"error_messages\": [\u001b[0m\u001b[48;2;240;248;255m                                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \"JSON does not match schema:\\n{\\n  \\\"$.action\\\": [\\n    \\\"{'flight_direction': 'north', 'distance':\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m3} is not valid under any of the given schemas\\\"\\n  ]\\n}\"\u001b[0m\u001b[48;2;240;248;255m                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  ]\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYou run into a giant. What do you do?\u001b[0m\u001b[48;2;240;248;255m                                                                  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHelp me correct the incorrect values based on the given error messages.\u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m                                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise.\u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere's an example of the structure:\u001b[0m\u001b[48;2;240;248;255m                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  \"action\": {\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \"chosen_action\": \"flight\",\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \"flight_direction\": \"few\",\u001b[0m\u001b[48;2;240;248;255m                                                                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \"distance\": 10\u001b[0m\u001b[48;2;240;248;255m                                                                                     \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m  }\u001b[0m\u001b[48;2;240;248;255m                                                                                                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m                                                                                                      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant only capable of communicating with valid JSON, and no other text.\u001b[0m\u001b[48;2;255;240;242m          \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;255;240;242m      \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;255;240;242m   \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242menter `null`.\u001b[0m\u001b[48;2;255;240;242m                                                                                          \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;255;240;242m                         \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;255;240;242m                    \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;255;240;242m   \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242metc.]}`\u001b[0m\u001b[48;2;255;240;242m                                                                                                \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;255;240;242m                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
+       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m                                                                                                       \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
        "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"action\": {\u001b[0m\u001b[48;2;245;245;220m                                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"chosen_action\": \"flight\",\u001b[0m\u001b[48;2;245;245;220m                                                                         \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"flight_direction\": \"north\",\u001b[0m\u001b[48;2;245;245;220m                                                                       \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"distance\": 1\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"distance\": 3\u001b[0m\u001b[48;2;245;245;220m                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  }\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    'action': {\u001b[0m\u001b[48;2;240;255;240m                                                                                        \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        'chosen_action': 'flight',\u001b[0m\u001b[48;2;240;255;240m                                                                     \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        'flight_direction': 'north',\u001b[0m\u001b[48;2;240;255;240m                                                                   \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        'distance': 1\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m        'distance': 3\u001b[0m\u001b[48;2;240;255;240m                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m    }\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m                                                                                                      \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
@@ -530,23 +767,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 15,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
-      "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "raw_llm_response, validated_response, *rest = guard(\n",
-    "    openai.chat.completions.create,\n",
+    "    messages=[{\"role\":\"user\", \"content\": prompt}],\n",
     "    prompt_params={'opp_type': 'goblin'},\n",
-    "    model=\"gpt-3.5-turbo\",\n",
+    "    model=\"gpt-4o\",\n",
     "    max_tokens=256,\n",
     "    temperature=0.0,\n",
     ")"
@@ -554,7 +782,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 16,
    "metadata": {},
    "outputs": [
     {
@@ -584,7 +812,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 17,
    "metadata": {},
    "outputs": [
     {
@@ -593,57 +821,62 @@
        "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ You are a human in an enchanted forest. You come across opponents of different types, and you should    │ │\n",
-       "    │ │ fight smaller opponents and run away from bigger ones.                                                  │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ You run into a goblin. What do you do?                                                                  │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <choice name=\"action\" discriminator=\"chosen_action\">                                                │ │\n",
-       "    │ │         <case name=\"fight\">                                                                             │ │\n",
-       "    │ │             <string name=\"weapon\" format=\"valid-choices: choices=['crossbow', 'machine gun']\"/>         │ │\n",
-       "    │ │         </case>                                                                                         │ │\n",
-       "    │ │         <case name=\"flight\">                                                                            │ │\n",
-       "    │ │             <string name=\"flight_direction\" format=\"valid-choices: choices=['north', 'south', 'east',   │ │\n",
-       "    │ │ 'west']\"/>                                                                                              │ │\n",
-       "    │ │             <integer name=\"distance\" format=\"valid-choices: choices=[1, 2, 3, 4]\"/>                     │ │\n",
-       "    │ │         </case>                                                                                         │ │\n",
-       "    │ │     </choice>                                                                                           │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise.                                 │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ You are a human in an enchanted forest. You come across opponents of different types, and    │ │ │\n",
+       "    │ │ │      │ you should fight smaller opponents and run away from bigger ones.                            │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ You run into a goblin. What do you do?                                                       │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <choice discriminator=\"chosen_action\" name=\"action\" required=\"true\">                       │ │ │\n",
+       "    │ │ │      │     <case name=\"fight\">                                                                      │ │ │\n",
+       "    │ │ │      │       <string format=\"guardrails/valid_choices: ['crossbow', 'machine gun']\" name=\"weapon\"   │ │ │\n",
+       "    │ │ │      │ required=\"true\"></string>                                                                    │ │ │\n",
+       "    │ │ │      │     </case>                                                                                  │ │ │\n",
+       "    │ │ │      │     <case name=\"flight\">                                                                     │ │ │\n",
+       "    │ │ │      │       <string format=\"guardrails/valid_choices: ['north', 'south', 'east', 'west']\"          │ │ │\n",
+       "    │ │ │      │ name=\"flight_direction\" required=\"true\"></string>                                            │ │ │\n",
+       "    │ │ │      │       <integer format=\"guardrails/valid_choices: [1, 2, 3, 4]\" name=\"distance\"               │ │ │\n",
+       "    │ │ │      │ required=\"true\"></integer>                                                                   │ │ │\n",
+       "    │ │ │      │     </case>                                                                                  │ │ │\n",
+       "    │ │ │      │   </choice>                                                                                  │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise.                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ ```json                                                                                                 │ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │   \"action\": {                                                                                           │ │\n",
        "    │ │     \"chosen_action\": \"fight\",                                                                           │ │\n",
        "    │ │     \"weapon\": \"crossbow\"                                                                                │ │\n",
        "    │ │   }                                                                                                     │ │\n",
        "    │ │ }                                                                                                       │ │\n",
+       "    │ │ ```                                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {'action': {'chosen_action': 'fight', 'weapon': 'crossbow'}}                                            │ │\n",
@@ -655,57 +888,62 @@
        "Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYou are a human in an enchanted forest. You come across opponents of different types, and you should \u001b[0m\u001b[48;2;240;248;255m  \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mfight smaller opponents and run away from bigger ones.\u001b[0m\u001b[48;2;240;248;255m                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYou run into a goblin. What do you do?\u001b[0m\u001b[48;2;240;248;255m                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                            \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                           \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                                                                                             \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m            \u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m        \u001b[0m\u001b[48;2;240;248;255m                                                                                        \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise.\u001b[0m\u001b[48;2;240;248;255m                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mYou are a human in an enchanted forest. You come across opponents of different types, and   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myou should fight smaller opponents and run away from bigger ones.                           \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mYou run into a goblin. What do you do?                                                      \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                 \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                     \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise.                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m                                                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"action\": {\u001b[0m\u001b[48;2;245;245;220m                                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"chosen_action\": \"fight\",\u001b[0m\u001b[48;2;245;245;220m                                                                          \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m    \"weapon\": \"crossbow\"\u001b[0m\u001b[48;2;245;245;220m                                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  }\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m                                                                                                    \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'action': {'chosen_action': 'fight', 'weapon': 'crossbow'}}\u001b[0m\u001b[48;2;240;255;240m                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -738,7 +976,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.6"
+   "version": "3.12.1"
   }
  },
  "nbformat": 4,
diff --git a/docs/examples/summarizer.ipynb b/docs/examples/summarizer.ipynb
new file mode 100644
index 000000000..24c40eb17
--- /dev/null
+++ b/docs/examples/summarizer.ipynb
@@ -0,0 +1,1207 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Summarizer\n",
+    "\n",
+    "In this example we will use Guardrails to summarize text in terms of length, quality and output read time.\n",
+    "\n",
+    "!!! note\n",
+    "    To download this example as a Jupyter notebook, click [here](https://github.com/ShreyaR/guardrails/blob/main/docs/examples/summarization.ipynb).\n",
+    "\n",
+    "In this example, we will use Guardrails in the summarization of a text document. We will check whether the summarized document has a high semantic similarity with the original document. We will ensure the ouptput meets a certain range of length and read time.\n",
+    "\n",
+    "## Setup\n",
+    "In order to check semantic similarity we will need the `numpy` package via the command below. We will also install the validators we indtend to use."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.2\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
+      "Note: you may need to restart the kernel to use updated packages.\n",
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mreading_time...\u001b[0m\n",
+      "✅Successfully installed guardrails/reading_time!\n",
+      "\n",
+      "\n",
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95msimilar_to_document...\u001b[0m\n",
+      "✅Successfully installed guardrails/similar_to_document!\n",
+      "\n",
+      "\n",
+      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mvalid_length...\u001b[0m\n",
+      "✅Successfully installed guardrails/valid_length!\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "%pip install numpy -q\n",
+    "! guardrails hub install hub://guardrails/reading_time --quiet --install-local-models\n",
+    "! guardrails hub install hub://guardrails/similar_to_document --quiet --install-local-models\n",
+    "! guardrails hub install hub://guardrails/valid_length --quiet --install-local-models"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Step 1: Load data and create Pydantic Model\n",
+    "\n",
+    "Load our text with the code below"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "with open(\"data/twain.txt\", \"r\") as file:\n",
+    "    document = file.read()\n",
+    "    file.seek(0)\n",
+    "    content = \"\".join(line.strip() for line in file.readlines())"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Next we can define our return output with a pydantic model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pydantic import BaseModel, Field\n",
+    "\n",
+    "from guardrails.hub import SimilarToDocument, ValidLength, ReadingTime\n",
+    "\n",
+    "prompt = \"\"\"\n",
+    "Summarize the following text faithfully:\n",
+    "\n",
+    "${document}\n",
+    "\n",
+    "${gr.complete_xml_suffix}\n",
+    "\"\"\"\n",
+    "\n",
+    "THREE_MINUTES = 180 / 60\n",
+    "\n",
+    "class TextSummary(BaseModel):\n",
+    "    summary: str = Field(\n",
+    "        description=\"Faithful summary of the text\",\n",
+    "        validators=[\n",
+    "            ReadingTime(reading_time=THREE_MINUTES, on_fail=\"exception\"),\n",
+    "            ValidLength(min=100, max=1000, on_fail=\"exception\"),\n",
+    "            SimilarToDocument(document=f\"'{content}'\", threshold=0.60, on_fail=\"filter\")\n",
+    "        ],\n",
+    "    )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Step 2 Create Guard from pydantic\n",
+    "\n",
+    "The guard we create will:\n",
+    "1. Enforce reading time\n",
+    "2. Enforce length\n",
+    "3. Enforce similarity"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import guardrails as gd\n",
+    "from guardrails.errors import ValidationError\n",
+    "\n",
+    "guard = gd.Guard().from_pydantic(TextSummary)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Step 3: Call LLM via `guard(`\n",
+    "\n",
+    "We use the tools api to ensure our data is returned in a structured form. \n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Similarity: 0.789, Type: \n",
+      "Validated Output: {'summary': \"Mark Twain discusses the art of storytelling, focusing on the humorous story, which he considers uniquely American. He contrasts it with the comic story, which is English, and the witty story, which is French. The humorous story relies on the manner of telling, can be lengthy, and often ends without a clear point. In contrast, comic and witty stories are brief and end with a punchline. Twain emphasizes that telling a humorous story requires high artistic skill, while anyone can tell comic or witty stories. He notes that humorous stories are told gravely, with the teller pretending not to know it's funny, whereas comic stories are told with obvious delight and emphasis on the punchline. Twain mentions that some storytellers, like Artemus Ward, use subtle techniques to deliver the punchline, while comic storytellers make it very obvious. He finds the latter approach less appealing.\"}\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "# TODO: Replace OPENAI_API_KEY with your OpenAI API key, uncomment\n",
+    "# os.environ[\"OPENAI_API_KEY\"] = \"OPENAI_API_KEY\"\n",
+    "\n",
+    "response = guard(\n",
+    "    messages=[{\"role\":\"user\", \"content\": prompt}],\n",
+    "    prompt_params={\"document\": document},\n",
+    "    model=\"gpt-4o\",\n",
+    "    tools=guard.json_function_calling_tool(),\n",
+    "    tool_choice=\"required\",\n",
+    ")\n",
+    "\n",
+    "print(f\"Validated Output: {response.validated_output}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We can see the step-wise history of the `Guard` object below:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
Logs\n",
+       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ Summarize the following text faithfully:                                                     │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ The Humorous Story an American Development.— Its                                             │ │ │\n",
+       "    │ │ │      │ Difference from Comic and Witty Stories.                                                     │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ DO not claim that I can tell a story as it ought to                                          │ │ │\n",
+       "    │ │ │      │ be told. I only claim to know how a story                                                    │ │ │\n",
+       "    │ │ │      │ ought to be told, for I have been almost daily in the                                        │ │ │\n",
+       "    │ │ │      │ company of the most expert story-tellers for many                                            │ │ │\n",
+       "    │ │ │      │ years.                                                                                       │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ There are several kinds of stories, but only one                                             │ │ │\n",
+       "    │ │ │      │ difficult kind —the humorous. I will talk mainly                                             │ │ │\n",
+       "    │ │ │      │ about that one. The humorous story is American,                                              │ │ │\n",
+       "    │ │ │      │ the comic story is English, the witty story is French.                                       │ │ │\n",
+       "    │ │ │      │ The humorous story depends for its effect upon the                                           │ │ │\n",
+       "    │ │ │      │ manner of the telling; the comic story and the witty                                         │ │ │\n",
+       "    │ │ │      │ story upon the matter.                                                                       │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ The humorous story may be spun out to great                                                  │ │ │\n",
+       "    │ │ │      │ length, and may wander around as much as it                                                  │ │ │\n",
+       "    │ │ │      │ pleases, and arrive nowhere in particular; but the                                           │ │ │\n",
+       "    │ │ │      │ comic and witty stories must be brief and end with                                           │ │ │\n",
+       "    │ │ │      │ a point. The humorous story bubbles gently along,                                            │ │ │\n",
+       "    │ │ │      │ the others burst.                                                                            │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ The humorous story is strictly a work of art —                                               │ │ │\n",
+       "    │ │ │      │ high and delicate art — and only an artist can tell it;                                      │ │ │\n",
+       "    │ │ │      │ but no art is necessary in telling the comic and the                                         │ │ │\n",
+       "    │ │ │      │ witty story; anybody can do it. The art of telling                                           │ │ │\n",
+       "    │ │ │      │ a humorous story — understand, I mean by word of                                             │ │ │\n",
+       "    │ │ │      │ mouth, not print — was created in America, and                                               │ │ │\n",
+       "    │ │ │      │ has remained at home.                                                                        │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ The humorous story is told gravely; the teller                                               │ │ │\n",
+       "    │ │ │      │ does his best to conceal the fact that he even dimly                                         │ │ │\n",
+       "    │ │ │      │ suspects that there is anything funny about it; but                                          │ │ │\n",
+       "    │ │ │      │ the teller of the comic story tells you beforehand                                           │ │ │\n",
+       "    │ │ │      │ that it is one of the funniest things he has ever                                            │ │ │\n",
+       "    │ │ │      │ heard, then tells it with eager delight, and is the                                          │ │ │\n",
+       "    │ │ │      │ first person to laugh when he gets through. And                                              │ │ │\n",
+       "    │ │ │      │ sometimes, if he has had good success, he is so glad                                         │ │ │\n",
+       "    │ │ │      │ and happy that he will repeat the ‘‘ nub’’ of it and                                         │ │ │\n",
+       "    │ │ │      │ slance around from face to face, collecting applause,                                        │ │ │\n",
+       "    │ │ │      │ and then repeat it again. It is a pathetic thing to                                          │ │ │\n",
+       "    │ │ │      │ see.                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Very often, of course, the rambling and disjointed                                           │ │ │\n",
+       "    │ │ │      │ humorous story finishes with a nub, point, snapper,                                          │ │ │\n",
+       "    │ │ │      │ or whatever you like to call it. Then the listener                                           │ │ │\n",
+       "    │ │ │      │ must be alert, for in many cases the teller will divert                                      │ │ │\n",
+       "    │ │ │      │ attention from that nub by dropping it in a carefully.                                       │ │ │\n",
+       "    │ │ │      │ casual and indifferent way, with the pretence that he                                        │ │ │\n",
+       "    │ │ │      │ does not know it is a nub.                                                                   │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Artemus Ward used that trick a good deal; then                                               │ │ │\n",
+       "    │ │ │      │ when the belated audience presently caught the joke                                          │ │ │\n",
+       "    │ │ │      │ he would look up with innocent surprise, as if                                               │ │ │\n",
+       "    │ │ │      │ wondering what they had found to laugh at. Dan                                               │ │ │\n",
+       "    │ │ │      │ Setchell used it before him, Nye and Riley and                                               │ │ │\n",
+       "    │ │ │      │ others use it to-day.                                                                        │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ But the teller of the comic story does not slur                                              │ │ │\n",
+       "    │ │ │      │ the nub; he shouts it at you—every time. And                                                 │ │ │\n",
+       "    │ │ │      │ when he prints it, in England, France, Germany,                                              │ │ │\n",
+       "    │ │ │      │ and Italy, he italicizes it, puts some whooping                                              │ │ │\n",
+       "    │ │ │      │ exclamation-points after it, and sometimes explains                                          │ │ │\n",
+       "    │ │ │      │ it in a parenthesis. All of which is very depressing,                                        │ │ │\n",
+       "    │ │ │      │ and makes one want to renounce joking and lead a                                             │ │ │\n",
+       "    │ │ │      │ better life.                                                                                 │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ - Mark Twain                                                                                 │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <string description=\"Faithful summary of the text\" format=\"guardrails/reading_time: 3.0;   │ │ │\n",
+       "    │ │ │      │ guardrails/valid_length: 100 1000; guardrails/similar_to_document: 'The Humorous Story an    │ │ │\n",
+       "    │ │ │      │ American Development.— ItsDifference from Comic and Witty Stories.DO not claim that I can    │ │ │\n",
+       "    │ │ │      │ tell a story as it ought tobe told. I only claim to know how a storyought to be told, for I  │ │ │\n",
+       "    │ │ │      │ have been almost daily in thecompany of the most expert story-tellers for manyyears.There    │ │ │\n",
+       "    │ │ │      │ are several kinds of stories, but only onedifficult kind —the humorous. I will talk          │ │ │\n",
+       "    │ │ │      │ mainlyabout that one. The humorous story is American,the comic story is English, the witty   │ │ │\n",
+       "    │ │ │      │ story is French.The humorous story depends for its effect upon themanner of the telling; the │ │ │\n",
+       "    │ │ │      │ comic story and the wittystory upon the matter.The humorous story may be spun out to         │ │ │\n",
+       "    │ │ │      │ greatlength, and may wander around as much as itpleases, and arrive nowhere in particular;   │ │ │\n",
+       "    │ │ │      │ but thecomic and witty stories must be brief and end witha point. The humorous story bubbles │ │ │\n",
+       "    │ │ │      │ gently along,the others burst.The humorous story is strictly a work of art —high and         │ │ │\n",
+       "    │ │ │      │ delicate art — and only an artist can tell it;but no art is necessary in telling the comic   │ │ │\n",
+       "    │ │ │      │ and thewitty story; anybody can do it. The art of tellinga humorous story — understand, I    │ │ │\n",
+       "    │ │ │      │ mean by word ofmouth, not print — was created in America, andhas remained at home.The        │ │ │\n",
+       "    │ │ │      │ humorous story is told gravely; the tellerdoes his best to conceal the fact that he even     │ │ │\n",
+       "    │ │ │      │ dimlysuspects that there is anything funny about it; butthe teller of the comic story tells  │ │ │\n",
+       "    │ │ │      │ you beforehandthat it is one of the funniest things he has everheard, then tells it with     │ │ │\n",
+       "    │ │ │      │ eager delight, and is thefirst person to laugh when he gets through. Andsometimes, if he has │ │ │\n",
+       "    │ │ │      │ had good success, he is so gladand happy that he will repeat the ‘‘ nub’’ of it andslance    │ │ │\n",
+       "    │ │ │      │ around from face to face, collecting applause,and then repeat it again. It is a pathetic     │ │ │\n",
+       "    │ │ │      │ thing tosee.Very often, of course, the rambling and disjointedhumorous story finishes with a │ │ │\n",
+       "    │ │ │      │ nub, point, snapper,or whatever you like to call it. Then the listenermust be alert, for in  │ │ │\n",
+       "    │ │ │      │ many cases the teller will divertattention from that nub by dropping it in a                 │ │ │\n",
+       "    │ │ │      │ carefully.casual and indifferent way, with the pretence that hedoes not know it is a         │ │ │\n",
+       "    │ │ │      │ nub.Artemus Ward used that trick a good deal; thenwhen the belated audience presently caught │ │ │\n",
+       "    │ │ │      │ the jokehe would look up with innocent surprise, as ifwondering what they had found to laugh │ │ │\n",
+       "    │ │ │      │ at. DanSetchell used it before him, Nye and Riley andothers use it to-day.But the teller of  │ │ │\n",
+       "    │ │ │      │ the comic story does not slurthe nub; he shouts it at you—every time. Andwhen he prints it,  │ │ │\n",
+       "    │ │ │      │ in England, France, Germany,and Italy, he italicizes it, puts some                           │ │ │\n",
+       "    │ │ │      │ whoopingexclamation-points after it, and sometimes explainsit in a parenthesis. All of which │ │ │\n",
+       "    │ │ │      │ is very depressing,and makes one want to renounce joking and lead abetter life.- Mark Twain' │ │ │\n",
+       "    │ │ │      │ 0.6 all-MiniLM-L6-v2\" name=\"summary\" required=\"true\"></string>                               │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ {\"summary\":\"Mark Twain discusses the art of storytelling, focusing on the humorous story, which he      │ │\n",
+       "    │ │ considers uniquely American. He contrasts it with the comic story, which is English, and the witty      │ │\n",
+       "    │ │ story, which is French. The humorous story relies on the manner of telling, can be lengthy, and often   │ │\n",
+       "    │ │ ends without a clear point. In contrast, comic and witty stories are brief and end with a punchline.    │ │\n",
+       "    │ │ Twain emphasizes that telling a humorous story requires high artistic skill, while anyone can tell      │ │\n",
+       "    │ │ comic or witty stories. He notes that humorous stories are told gravely, with the teller pretending not │ │\n",
+       "    │ │ to know it's funny, whereas comic stories are told with obvious delight and emphasis on the punchline.  │ │\n",
+       "    │ │ Twain mentions that some storytellers, like Artemus Ward, use subtle techniques to deliver the          │ │\n",
+       "    │ │ punchline, while comic storytellers make it very obvious. He finds the latter approach less             │ │\n",
+       "    │ │ appealing.\"}                                                                                            │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │     'summary': \"Mark Twain discusses the art of storytelling, focusing on the humorous story, which he  │ │\n",
+       "    │ │ considers uniquely American. He contrasts it with the comic story, which is English, and the witty      │ │\n",
+       "    │ │ story, which is French. The humorous story relies on the manner of telling, can be lengthy, and often   │ │\n",
+       "    │ │ ends without a clear point. In contrast, comic and witty stories are brief and end with a punchline.    │ │\n",
+       "    │ │ Twain emphasizes that telling a humorous story requires high artistic skill, while anyone can tell      │ │\n",
+       "    │ │ comic or witty stories. He notes that humorous stories are told gravely, with the teller pretending not │ │\n",
+       "    │ │ to know it's funny, whereas comic stories are told with obvious delight and emphasis on the punchline.  │ │\n",
+       "    │ │ Twain mentions that some storytellers, like Artemus Ward, use subtle techniques to deliver the          │ │\n",
+       "    │ │ punchline, while comic storytellers make it very obvious. He finds the latter approach less appealing.\" │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "Logs\n", + "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSummarize the following text faithfully: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe Humorous Story an American Development.— Its \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mDifference from Comic and Witty Stories. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mDO not claim that I can tell a story as it ought to \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbe told. I only claim to know how a story \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mought to be told, for I have been almost daily in the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcompany of the most expert story-tellers for many \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myears. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThere are several kinds of stories, but only one \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdifficult kind —the humorous. I will talk mainly \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout that one. The humorous story is American, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe comic story is English, the witty story is French. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story depends for its effect upon the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmanner of the telling; the comic story and the witty \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mstory upon the matter. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story may be spun out to great \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mlength, and may wander around as much as it \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mpleases, and arrive nowhere in particular; but the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcomic and witty stories must be brief and end with \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma point. The humorous story bubbles gently along, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe others burst. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story is strictly a work of art — \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhigh and delicate art — and only an artist can tell it; \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbut no art is necessary in telling the comic and the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwitty story; anybody can do it. The art of telling \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma humorous story — understand, I mean by word of \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmouth, not print — was created in America, and \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhas remained at home. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story is told gravely; the teller \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdoes his best to conceal the fact that he even dimly \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msuspects that there is anything funny about it; but \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe teller of the comic story tells you beforehand \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthat it is one of the funniest things he has ever \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mheard, then tells it with eager delight, and is the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mfirst person to laugh when he gets through. And \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msometimes, if he has had good success, he is so glad \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand happy that he will repeat the ‘‘ nub’’ of it and \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mslance around from face to face, collecting applause, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand then repeat it again. It is a pathetic thing to \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msee. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mVery often, of course, the rambling and disjointed \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhumorous story finishes with a nub, point, snapper, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mor whatever you like to call it. Then the listener \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmust be alert, for in many cases the teller will divert \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mattention from that nub by dropping it in a carefully. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcasual and indifferent way, with the pretence that he \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdoes not know it is a nub. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mArtemus Ward used that trick a good deal; then \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwhen the belated audience presently caught the joke \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhe would look up with innocent surprise, as if \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwondering what they had found to laugh at. Dan \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSetchell used it before him, Nye and Riley and \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mothers use it to-day. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mBut the teller of the comic story does not slur \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe nub; he shouts it at you—every time. And \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwhen he prints it, in England, France, Germany, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand Italy, he italicizes it, puts some whooping \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mexclamation-points after it, and sometimes explains \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mit in a parenthesis. All of which is very depressing, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand makes one want to renounce joking and lead a \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbetter life. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- Mark Twain \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE', \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index': \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\"summary\":\"Mark Twain discusses the art of storytelling, focusing on the humorous story, which he \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mconsiders uniquely American. He contrasts it with the comic story, which is English, and the witty \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mstory, which is French. The humorous story relies on the manner of telling, can be lengthy, and often \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mends without a clear point. In contrast, comic and witty stories are brief and end with a punchline. \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mTwain emphasizes that telling a humorous story requires high artistic skill, while anyone can tell \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mcomic or witty stories. He notes that humorous stories are told gravely, with the teller pretending not\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mto know it's funny, whereas comic stories are told with obvious delight and emphasis on the punchline. \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mTwain mentions that some storytellers, like Artemus Ward, use subtle techniques to deliver the \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mpunchline, while comic storytellers make it very obvious. He finds the latter approach less \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mappealing.\"}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'summary': \"Mark Twain discusses the art of storytelling, focusing on the humorous story, which he \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mconsiders uniquely American. He contrasts it with the comic story, which is English, and the witty \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mstory, which is French. The humorous story relies on the manner of telling, can be lengthy, and often \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mends without a clear point. In contrast, comic and witty stories are brief and end with a punchline. \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mTwain emphasizes that telling a humorous story requires high artistic skill, while anyone can tell \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mcomic or witty stories. He notes that humorous stories are told gravely, with the teller pretending not\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mto know it's funny, whereas comic stories are told with obvious delight and emphasis on the punchline. \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mTwain mentions that some storytellers, like Artemus Ward, use subtle techniques to deliver the \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mpunchline, while comic storytellers make it very obvious. He finds the latter approach less appealing.\"\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "guard.history.last.tree" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `guard` wrapper returns the raw_llm_respose (which is a simple string), and the validated and corrected output (which is a dictionary). We can see that the output is a dictionary with the correct schema and types.\n", + "\n", + "Now lets try a model thats not as proficent at summarization and we can see the ouptput is filtered and validation has failed.\n", + "\n", + "The final validated output is `None` due to the failed validation." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validated Output: None\n" + ] + } + ], + "source": [ + "response = guard(\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={\"document\": document},\n", + " model=\"babbage-002\",\n", + " max_tokens=512,\n", + " temperature=0,\n", + ")\n", + "\n", + "print(f\"Validated Output: {response.validated_output}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see the step wise history of the guard execution below:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Logs\n",
+       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
+       "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "│   │ │ No prompt                                                                                               │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "│   │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "│   │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "│   │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "│   │ │ │ user │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Summarize the following text faithfully:                                                     │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ The Humorous Story an American Development.— Its                                             │ │ │\n",
+       "│   │ │ │      │ Difference from Comic and Witty Stories.                                                     │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ DO not claim that I can tell a story as it ought to                                          │ │ │\n",
+       "│   │ │ │      │ be told. I only claim to know how a story                                                    │ │ │\n",
+       "│   │ │ │      │ ought to be told, for I have been almost daily in the                                        │ │ │\n",
+       "│   │ │ │      │ company of the most expert story-tellers for many                                            │ │ │\n",
+       "│   │ │ │      │ years.                                                                                       │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ There are several kinds of stories, but only one                                             │ │ │\n",
+       "│   │ │ │      │ difficult kind —the humorous. I will talk mainly                                             │ │ │\n",
+       "│   │ │ │      │ about that one. The humorous story is American,                                              │ │ │\n",
+       "│   │ │ │      │ the comic story is English, the witty story is French.                                       │ │ │\n",
+       "│   │ │ │      │ The humorous story depends for its effect upon the                                           │ │ │\n",
+       "│   │ │ │      │ manner of the telling; the comic story and the witty                                         │ │ │\n",
+       "│   │ │ │      │ story upon the matter.                                                                       │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ The humorous story may be spun out to great                                                  │ │ │\n",
+       "│   │ │ │      │ length, and may wander around as much as it                                                  │ │ │\n",
+       "│   │ │ │      │ pleases, and arrive nowhere in particular; but the                                           │ │ │\n",
+       "│   │ │ │      │ comic and witty stories must be brief and end with                                           │ │ │\n",
+       "│   │ │ │      │ a point. The humorous story bubbles gently along,                                            │ │ │\n",
+       "│   │ │ │      │ the others burst.                                                                            │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ The humorous story is strictly a work of art —                                               │ │ │\n",
+       "│   │ │ │      │ high and delicate art — and only an artist can tell it;                                      │ │ │\n",
+       "│   │ │ │      │ but no art is necessary in telling the comic and the                                         │ │ │\n",
+       "│   │ │ │      │ witty story; anybody can do it. The art of telling                                           │ │ │\n",
+       "│   │ │ │      │ a humorous story — understand, I mean by word of                                             │ │ │\n",
+       "│   │ │ │      │ mouth, not print — was created in America, and                                               │ │ │\n",
+       "│   │ │ │      │ has remained at home.                                                                        │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ The humorous story is told gravely; the teller                                               │ │ │\n",
+       "│   │ │ │      │ does his best to conceal the fact that he even dimly                                         │ │ │\n",
+       "│   │ │ │      │ suspects that there is anything funny about it; but                                          │ │ │\n",
+       "│   │ │ │      │ the teller of the comic story tells you beforehand                                           │ │ │\n",
+       "│   │ │ │      │ that it is one of the funniest things he has ever                                            │ │ │\n",
+       "│   │ │ │      │ heard, then tells it with eager delight, and is the                                          │ │ │\n",
+       "│   │ │ │      │ first person to laugh when he gets through. And                                              │ │ │\n",
+       "│   │ │ │      │ sometimes, if he has had good success, he is so glad                                         │ │ │\n",
+       "│   │ │ │      │ and happy that he will repeat the ‘‘ nub’’ of it and                                         │ │ │\n",
+       "│   │ │ │      │ slance around from face to face, collecting applause,                                        │ │ │\n",
+       "│   │ │ │      │ and then repeat it again. It is a pathetic thing to                                          │ │ │\n",
+       "│   │ │ │      │ see.                                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Very often, of course, the rambling and disjointed                                           │ │ │\n",
+       "│   │ │ │      │ humorous story finishes with a nub, point, snapper,                                          │ │ │\n",
+       "│   │ │ │      │ or whatever you like to call it. Then the listener                                           │ │ │\n",
+       "│   │ │ │      │ must be alert, for in many cases the teller will divert                                      │ │ │\n",
+       "│   │ │ │      │ attention from that nub by dropping it in a carefully.                                       │ │ │\n",
+       "│   │ │ │      │ casual and indifferent way, with the pretence that he                                        │ │ │\n",
+       "│   │ │ │      │ does not know it is a nub.                                                                   │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Artemus Ward used that trick a good deal; then                                               │ │ │\n",
+       "│   │ │ │      │ when the belated audience presently caught the joke                                          │ │ │\n",
+       "│   │ │ │      │ he would look up with innocent surprise, as if                                               │ │ │\n",
+       "│   │ │ │      │ wondering what they had found to laugh at. Dan                                               │ │ │\n",
+       "│   │ │ │      │ Setchell used it before him, Nye and Riley and                                               │ │ │\n",
+       "│   │ │ │      │ others use it to-day.                                                                        │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ But the teller of the comic story does not slur                                              │ │ │\n",
+       "│   │ │ │      │ the nub; he shouts it at you—every time. And                                                 │ │ │\n",
+       "│   │ │ │      │ when he prints it, in England, France, Germany,                                              │ │ │\n",
+       "│   │ │ │      │ and Italy, he italicizes it, puts some whooping                                              │ │ │\n",
+       "│   │ │ │      │ exclamation-points after it, and sometimes explains                                          │ │ │\n",
+       "│   │ │ │      │ it in a parenthesis. All of which is very depressing,                                        │ │ │\n",
+       "│   │ │ │      │ and makes one want to renounce joking and lead a                                             │ │ │\n",
+       "│   │ │ │      │ better life.                                                                                 │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ - Mark Twain                                                                                 │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "│   │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ <output>                                                                                     │ │ │\n",
+       "│   │ │ │      │   <string description=\"Faithful summary of the text\" format=\"guardrails/reading_time: 3.0;   │ │ │\n",
+       "│   │ │ │      │ guardrails/valid_length: 100 1000; guardrails/similar_to_document: 'The Humorous Story an    │ │ │\n",
+       "│   │ │ │      │ American Development.— ItsDifference from Comic and Witty Stories.DO not claim that I can    │ │ │\n",
+       "│   │ │ │      │ tell a story as it ought tobe told. I only claim to know how a storyought to be told, for I  │ │ │\n",
+       "│   │ │ │      │ have been almost daily in thecompany of the most expert story-tellers for manyyears.There    │ │ │\n",
+       "│   │ │ │      │ are several kinds of stories, but only onedifficult kind —the humorous. I will talk          │ │ │\n",
+       "│   │ │ │      │ mainlyabout that one. The humorous story is American,the comic story is English, the witty   │ │ │\n",
+       "│   │ │ │      │ story is French.The humorous story depends for its effect upon themanner of the telling; the │ │ │\n",
+       "│   │ │ │      │ comic story and the wittystory upon the matter.The humorous story may be spun out to         │ │ │\n",
+       "│   │ │ │      │ greatlength, and may wander around as much as itpleases, and arrive nowhere in particular;   │ │ │\n",
+       "│   │ │ │      │ but thecomic and witty stories must be brief and end witha point. The humorous story bubbles │ │ │\n",
+       "│   │ │ │      │ gently along,the others burst.The humorous story is strictly a work of art —high and         │ │ │\n",
+       "│   │ │ │      │ delicate art — and only an artist can tell it;but no art is necessary in telling the comic   │ │ │\n",
+       "│   │ │ │      │ and thewitty story; anybody can do it. The art of tellinga humorous story — understand, I    │ │ │\n",
+       "│   │ │ │      │ mean by word ofmouth, not print — was created in America, andhas remained at home.The        │ │ │\n",
+       "│   │ │ │      │ humorous story is told gravely; the tellerdoes his best to conceal the fact that he even     │ │ │\n",
+       "│   │ │ │      │ dimlysuspects that there is anything funny about it; butthe teller of the comic story tells  │ │ │\n",
+       "│   │ │ │      │ you beforehandthat it is one of the funniest things he has everheard, then tells it with     │ │ │\n",
+       "│   │ │ │      │ eager delight, and is thefirst person to laugh when he gets through. Andsometimes, if he has │ │ │\n",
+       "│   │ │ │      │ had good success, he is so gladand happy that he will repeat the ‘‘ nub’’ of it andslance    │ │ │\n",
+       "│   │ │ │      │ around from face to face, collecting applause,and then repeat it again. It is a pathetic     │ │ │\n",
+       "│   │ │ │      │ thing tosee.Very often, of course, the rambling and disjointedhumorous story finishes with a │ │ │\n",
+       "│   │ │ │      │ nub, point, snapper,or whatever you like to call it. Then the listenermust be alert, for in  │ │ │\n",
+       "│   │ │ │      │ many cases the teller will divertattention from that nub by dropping it in a                 │ │ │\n",
+       "│   │ │ │      │ carefully.casual and indifferent way, with the pretence that hedoes not know it is a         │ │ │\n",
+       "│   │ │ │      │ nub.Artemus Ward used that trick a good deal; thenwhen the belated audience presently caught │ │ │\n",
+       "│   │ │ │      │ the jokehe would look up with innocent surprise, as ifwondering what they had found to laugh │ │ │\n",
+       "│   │ │ │      │ at. DanSetchell used it before him, Nye and Riley andothers use it to-day.But the teller of  │ │ │\n",
+       "│   │ │ │      │ the comic story does not slurthe nub; he shouts it at you—every time. Andwhen he prints it,  │ │ │\n",
+       "│   │ │ │      │ in England, France, Germany,and Italy, he italicizes it, puts some                           │ │ │\n",
+       "│   │ │ │      │ whoopingexclamation-points after it, and sometimes explainsit in a parenthesis. All of which │ │ │\n",
+       "│   │ │ │      │ is very depressing,and makes one want to renounce joking and lead abetter life.- Mark Twain' │ │ │\n",
+       "│   │ │ │      │ 0.6 all-MiniLM-L6-v2\" name=\"summary\" required=\"true\"></string>                               │ │ │\n",
+       "│   │ │ │      │ </output>                                                                                    │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "│   │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "│   │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "│   │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "│   │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "│   │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "│   │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "│   │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "│   │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "│   │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "│   │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ │      │                                                                                              │ │ │\n",
+       "│   │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "│   │ │ The following XML is invalid:                                                                           │ │\n",
+       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "│   │ │ etc.]}`                                                                                                 │ │\n",
+       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "│   │ │                                                                                                         │ │\n",
+       "│   │ │ The following JSON is invalid:                                                                          │ │\n",
+       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "│   │ │ etc.]}`                                                                                                 │ │\n",
+       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "│   │ │                                                                                                         │ │\n",
+       "│   │ │ The following XML is valid:                                                                             │ │\n",
+       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "│   │ │ etc.]}`                                                                                                 │ │\n",
+       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "│   │ │                                                                                                         │ │\n",
+       "│   │ │ The following JSON is valid:                                                                            │ │\n",
+       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "│   │ │ etc.]}`                                                                                                 │ │\n",
+       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "│   │ │                                                                                                         │ │\n",
+       "│   │ │ The following XML is valid:                                                                             │ │\n",
+       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "│   │ │ - `<list                                                                                                │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "│   │ │ None                                                                                                    │ │\n",
+       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
+       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ I was given the following response, which was not parseable as JSON.                                    │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ \"The following XML is invalid:\\n- `<string name='foo' format='two-words lower-case' />` => `{'foo':     │ │\n",
+       "    │ │ 'example one'}`\\n- `<list name='bar'><string format='upper-case' /></list>` => `{\\\"bar\\\": ['STRING      │ │\n",
+       "    │ │ ONE', 'STRING TWO', etc.]}`\\n- `<object name='baz'><string name=\\\"foo\\\" format=\\\"capitalize two-words\\\" │ │\n",
+       "    │ │ /><integer name=\\\"index\\\" format=\\\"1-indexed\\\" /></object>` => `{'baz': {'foo': 'Some String', 'index': │ │\n",
+       "    │ │ 1}}`\\n\\nThe following JSON is invalid:\\n- `<string name='foo' format='two-words lower-case' />` =>      │ │\n",
+       "    │ │ `{'foo': 'example one'}`\\n- `<list name='bar'><string format='upper-case' /></list>` => `{\\\"bar\\\":      │ │\n",
+       "    │ │ ['STRING ONE', 'STRING TWO', etc.]}`\\n- `<object name='baz'><string name=\\\"foo\\\" format=\\\"capitalize    │ │\n",
+       "    │ │ two-words\\\" /><integer name=\\\"index\\\" format=\\\"1-indexed\\\" /></object>` => `{'baz': {'foo': 'Some       │ │\n",
+       "    │ │ String', 'index': 1}}`\\n\\nThe following XML is valid:\\n- `<string name='foo' format='two-words          │ │\n",
+       "    │ │ lower-case' />` => `{'foo': 'example one'}`\\n- `<list name='bar'><string format='upper-case' /></list>` │ │\n",
+       "    │ │ => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- `<object name='baz'><string name=\\\"foo\\\"          │ │\n",
+       "    │ │ format=\\\"capitalize two-words\\\" /><integer name=\\\"index\\\" format=\\\"1-indexed\\\" /></object>` => `{'baz': │ │\n",
+       "    │ │ {'foo': 'Some String', 'index': 1}}`\\n\\nThe following JSON is valid:\\n- `<string name='foo'             │ │\n",
+       "    │ │ format='two-words lower-case' />` => `{'foo': 'example one'}`\\n- `<list name='bar'><string              │ │\n",
+       "    │ │ format='upper-case' /></list>` => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- `<object           │ │\n",
+       "    │ │ name='baz'><string name=\\\"foo\\\" format=\\\"capitalize two-words\\\" /><integer name=\\\"index\\\"               │ │\n",
+       "    │ │ format=\\\"1-indexed\\\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`\\n\\nThe following XML │ │\n",
+       "    │ │ is valid:\\n- `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`\\n-       │ │\n",
+       "    │ │ `<list\"                                                                                                 │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Help me correct this by making it valid JSON.                                                           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
+       "    │ │ it into.                                                                                                │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ <output>                                                                                                │ │\n",
+       "    │ │   <string description=\"Faithful summary of the text\" format=\"guardrails/reading_time: 3.0;              │ │\n",
+       "    │ │ guardrails/valid_length: 100 1000; guardrails/similar_to_document: 'The Humorous Story an American      │ │\n",
+       "    │ │ Development.— ItsDifference from Comic and Witty Stories.DO not claim that I can tell a story as it     │ │\n",
+       "    │ │ ought tobe told. I only claim to know how a storyought to be told, for I have been almost daily in      │ │\n",
+       "    │ │ thecompany of the most expert story-tellers for manyyears.There are several kinds of stories, but only  │ │\n",
+       "    │ │ onedifficult kind —the humorous. I will talk mainlyabout that one. The humorous story is American,the   │ │\n",
+       "    │ │ comic story is English, the witty story is French.The humorous story depends for its effect upon        │ │\n",
+       "    │ │ themanner of the telling; the comic story and the wittystory upon the matter.The humorous story may be  │ │\n",
+       "    │ │ spun out to greatlength, and may wander around as much as itpleases, and arrive nowhere in particular;  │ │\n",
+       "    │ │ but thecomic and witty stories must be brief and end witha point. The humorous story bubbles gently     │ │\n",
+       "    │ │ along,the others burst.The humorous story is strictly a work of art —high and delicate art — and only   │ │\n",
+       "    │ │ an artist can tell it;but no art is necessary in telling the comic and thewitty story; anybody can do   │ │\n",
+       "    │ │ it. The art of tellinga humorous story — understand, I mean by word ofmouth, not print — was created in │ │\n",
+       "    │ │ America, andhas remained at home.The humorous story is told gravely; the tellerdoes his best to conceal │ │\n",
+       "    │ │ the fact that he even dimlysuspects that there is anything funny about it; butthe teller of the comic   │ │\n",
+       "    │ │ story tells you beforehandthat it is one of the funniest things he has everheard, then tells it with    │ │\n",
+       "    │ │ eager delight, and is thefirst person to laugh when he gets through. Andsometimes, if he has had good   │ │\n",
+       "    │ │ success, he is so gladand happy that he will repeat the ‘‘ nub’’ of it andslance around from face to    │ │\n",
+       "    │ │ face, collecting applause,and then repeat it again. It is a pathetic thing tosee.Very often, of course, │ │\n",
+       "    │ │ the rambling and disjointedhumorous story finishes with a nub, point, snapper,or whatever you like to   │ │\n",
+       "    │ │ call it. Then the listenermust be alert, for in many cases the teller will divertattention from that    │ │\n",
+       "    │ │ nub by dropping it in a carefully.casual and indifferent way, with the pretence that hedoes not know it │ │\n",
+       "    │ │ is a nub.Artemus Ward used that trick a good deal; thenwhen the belated audience presently caught the   │ │\n",
+       "    │ │ jokehe would look up with innocent surprise, as ifwondering what they had found to laugh at.            │ │\n",
+       "    │ │ DanSetchell used it before him, Nye and Riley andothers use it to-day.But the teller of the comic story │ │\n",
+       "    │ │ does not slurthe nub; he shouts it at you—every time. Andwhen he prints it, in England, France,         │ │\n",
+       "    │ │ Germany,and Italy, he italicizes it, puts some whoopingexclamation-points after it, and sometimes       │ │\n",
+       "    │ │ explainsit in a parenthesis. All of which is very depressing,and makes one want to renounce joking and  │ │\n",
+       "    │ │ lead abetter life.- Mark Twain' 0.6 all-MiniLM-L6-v2\" name=\"summary\" required=\"true\"></string>          │ │\n",
+       "    │ │ </output>                                                                                               │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
+       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
+       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
+       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
+       "    │ │ enter `null`.                                                                                           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ You are a helpful assistant only capable of communicating with valid JSON, and no other text.           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
+       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
+       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
+       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
+       "    │ │ enter `null`.                                                                                           │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
+       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
+       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "    │ │ etc.]}`                                                                                                 │ │\n",
+       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
+       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
+       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`\\n- `<list           │ │\n",
+       "    │ │ name='bar'><string format='upper-case' /></list>` => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- │ │\n",
+       "    │ │ `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"            │ │\n",
+       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`\\n\\nThe following XML   │ │\n",
+       "    │ │ is invalid:\\n- `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`\\n-     │ │\n",
+       "    │ │ `<list name='bar'><string format='upper-case' /></list>` => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO',     │ │\n",
+       "    │ │ etc.]}`\\n- `<object name='baz'><string name=\\\"foo\\\" format=\\\"capitalize two-words\\\" /><integer          │ │\n",
+       "    │ │ name=\\\"index\\\" format=\\\"1-indexed\\\" /></object>` => `{'baz': {'foo': 'Some String', 'index':            │ │\n",
+       "    │ │ 1}}`\\n\\nThe following JSON is invalid:\\n- `<string name='foo' format='two-words lower-case' />` =>      │ │\n",
+       "    │ │ `{'foo': 'example one'}`\\n- `<list name='bar'><string format='upper-case' /></list>` => `{\\\"bar\\\":      │ │\n",
+       "    │ │ ['STRING ONE', 'STRING TWO', etc.]}`\\n- `<object name='baz'><string name=\\\"foo\\\" format=\\\"capitalize    │ │\n",
+       "    │ │ two-words\\\" /><integer name=\\\"index\\\" format=\\\"1-indexed\\\" /></object>` => `{'baz': {'foo': 'Some       │ │\n",
+       "    │ │ String', 'index': 1}}`\\n\\nThe following XML is valid:\\n- `<string name='foo' format='two-words          │ │\n",
+       "    │ │ lower-case' />` => `{'foo': 'example one'}`\\n- `<list name='bar'><string format='upper-case' /></list>` │ │\n",
+       "    │ │ => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- `<object name='baz'><string name=\\\"foo\\\"          │ │\n",
+       "    │ │ format=\\\"capitalize two-words\\\" /><integer name=\\\"index\\\" format=\\\"1-indexed\\\" /></object>` => `{'baz': │ │\n",
+       "    │ │ {'foo': 'Some String', 'index': 1}}`\\n\\nThe following                                                   │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "    │ │ None                                                                                                    │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "Logs\n", + "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", + "│ │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSummarize the following text faithfully: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe Humorous Story an American Development.— Its \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mDifference from Comic and Witty Stories. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mDO not claim that I can tell a story as it ought to \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbe told. I only claim to know how a story \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mought to be told, for I have been almost daily in the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcompany of the most expert story-tellers for many \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235myears. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThere are several kinds of stories, but only one \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdifficult kind —the humorous. I will talk mainly \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mabout that one. The humorous story is American, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe comic story is English, the witty story is French. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story depends for its effect upon the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmanner of the telling; the comic story and the witty \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mstory upon the matter. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story may be spun out to great \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mlength, and may wander around as much as it \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mpleases, and arrive nowhere in particular; but the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcomic and witty stories must be brief and end with \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma point. The humorous story bubbles gently along, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe others burst. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story is strictly a work of art — \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhigh and delicate art — and only an artist can tell it; \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbut no art is necessary in telling the comic and the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwitty story; anybody can do it. The art of telling \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235ma humorous story — understand, I mean by word of \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmouth, not print — was created in America, and \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhas remained at home. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mThe humorous story is told gravely; the teller \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdoes his best to conceal the fact that he even dimly \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msuspects that there is anything funny about it; but \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe teller of the comic story tells you beforehand \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthat it is one of the funniest things he has ever \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mheard, then tells it with eager delight, and is the \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mfirst person to laugh when he gets through. And \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msometimes, if he has had good success, he is so glad \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand happy that he will repeat the ‘‘ nub’’ of it and \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mslance around from face to face, collecting applause, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand then repeat it again. It is a pathetic thing to \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235msee. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mVery often, of course, the rambling and disjointed \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhumorous story finishes with a nub, point, snapper, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mor whatever you like to call it. Then the listener \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mmust be alert, for in many cases the teller will divert \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mattention from that nub by dropping it in a carefully. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcasual and indifferent way, with the pretence that he \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mdoes not know it is a nub. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mArtemus Ward used that trick a good deal; then \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwhen the belated audience presently caught the joke \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mhe would look up with innocent surprise, as if \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwondering what they had found to laugh at. Dan \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSetchell used it before him, Nye and Riley and \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mothers use it to-day. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mBut the teller of the comic story does not slur \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mthe nub; he shouts it at you—every time. And \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mwhen he prints it, in England, France, Germany, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand Italy, he italicizes it, puts some whooping \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mexclamation-points after it, and sometimes explains \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mit in a parenthesis. All of which is very depressing, \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mand makes one want to renounce joking and lead a \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mbetter life. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- Mark Twain \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE', \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index': \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + "│ │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mThe following XML is invalid:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220metc.]}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mThe following JSON is invalid:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220metc.]}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mThe following XML is valid:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220metc.]}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mThe following JSON is valid:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220metc.]}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mThe following XML is valid:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m'example one'}`\\n- `` => `{\\\"bar\\\": ['STRING \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONE', 'STRING TWO', etc.]}`\\n- `` => `{'baz': {'foo': 'Some String', 'index':\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m1}}`\\n\\nThe following JSON is invalid:\\n- `` => \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`{'foo': 'example one'}`\\n- `` => `{\\\"bar\\\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m['STRING ONE', 'STRING TWO', etc.]}`\\n- `` => `{'baz': {'foo': 'Some \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mString', 'index': 1}}`\\n\\nThe following XML is valid:\\n- `` => `{'foo': 'example one'}`\\n- ``\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m=> `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- `` => `{'baz':\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{'foo': 'Some String', 'index': 1}}`\\n\\nThe following JSON is valid:\\n- `` => `{'foo': 'example one'}`\\n- `` => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\\n\\nThe following XML\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mis valid:\\n- `` => `{'foo': 'example one'}`\\n- \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant only capable of communicating with valid JSON, and no other text.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242menter `null`.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242metc.]}`\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", + " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m- `` => `{'foo': 'example one'}`\\n- `` => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n-\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m`` => `{'baz': {'foo': 'Some String', 'index': 1}}`\\n\\nThe following XML \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mis invalid:\\n- `` => `{'foo': 'example one'}`\\n- \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m`` => `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220metc.]}`\\n- `` => `{'baz': {'foo': 'Some String', 'index': \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m1}}`\\n\\nThe following JSON is invalid:\\n- `` => \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m`{'foo': 'example one'}`\\n- `` => `{\\\"bar\\\": \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m['STRING ONE', 'STRING TWO', etc.]}`\\n- `` => `{'baz': {'foo': 'Some \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mString', 'index': 1}}`\\n\\nThe following XML is valid:\\n- `` => `{'foo': 'example one'}`\\n- ``\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m=> `{\\\"bar\\\": ['STRING ONE', 'STRING TWO', etc.]}`\\n- `` => `{'baz':\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{'foo': 'Some String', 'index': 1}}`\\n\\nThe following\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mNone\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", + " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "guard.history.last.tree" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/syntax_error_free_sql.ipynb b/docs/examples/syntax_error_free_sql.ipynb index 30adf2121..b8a944a79 100644 --- a/docs/examples/syntax_error_free_sql.ipynb +++ b/docs/examples/syntax_error_free_sql.ipynb @@ -2,11 +2,22 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mvalid_sql...\u001b[0m\n", + "✅Successfully installed guardrails/valid_sql!\n", + "\n", + "\n" + ] + } + ], "source": [ - "!guardrails hub install hub://guardrails/valid_sql" + "!guardrails hub install hub://guardrails/valid_sql --quiet" ] }, { @@ -32,22 +43,21 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: sqlvalidator in /home/zayd/workspace/guardrails/.venv/lib/python3.9/site-packages (0.0.20)\n", "\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.2\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" ] } ], "source": [ - "! pip install sqlvalidator" + "! pip install sqlvalidator -q" ] }, { @@ -73,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -96,7 +106,7 @@ "\n", "${nl_instruction}\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\n", "\n", "\n", @@ -113,15 +123,15 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/home/zayd/workspace/guardrails/.venv/lib/python3.9/site-packages/torch/cuda/__init__.py:611: UserWarning: Can't initialize NVML\n", - " warnings.warn(\"Can't initialize NVML\")\n" + "/Users/dtam/.pyenv/versions/3.12.1/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n", + " from tqdm.autonotebook import tqdm, trange\n" ] } ], @@ -135,7 +145,7 @@ "\n", "${nl_instruction}\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\"\"\"\n", "\n", "class ValidSql(BaseModel):\n", @@ -167,7 +177,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -185,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -201,11 +211,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "guard = gd.Guard.from_pydantic(output_class=ValidSql, prompt=prompt)" + "guard = gd.Guard.from_pydantic(output_class=ValidSql)" ] }, { @@ -213,12 +223,48 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see the prompt that will be sent to the LLM:" + "Here, `nl_language` is the natural language instruction and will be provided by the user at runtime." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Wrap the LLM API call with `Guard`" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "raw_llm_response, validated_response, *rest = guard(\n", + " model=\"gpt-4o\",\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={\n", + " \"nl_instruction\": \"Select the name of the employee who has the highest salary.\"\n", + " },\n", + " max_tokens=2048,\n", + " temperature=0,\n", + ")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see the prompt that was sent to the LLM:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -228,17 +274,16 @@ "\n", "Generate a valid SQL query for the following natural language instruction:\n", "\n", - "${nl_instruction}\n", + "Select the name of the employee who has the highest salary.\n", "\n", "\n", "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "<output>\n", - " <string name=\"generated_sql\" description=\"Generate SQL for the given natural language instruction.\" \n", - "format=\"bug-free-sql\"/>\n", + " <string description=\"Generate SQL for the given natural language instruction.\" format=\"guardrails/valid_sql: None\n", + "None\" name=\"generated_sql\" required=\"true\"></string>\n", "</output>\n", "\n", - "\n", "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n", "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n", "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n", @@ -258,17 +303,16 @@ "\n", "Generate a valid SQL query for the following natural language instruction:\n", "\n", - "$\u001b[1m{\u001b[0mnl_instruction\u001b[1m}\u001b[0m\n", + "Select the name of the employee who has the highest salary.\n", "\n", "\n", "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", "\n", "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", + "\u001b[39m <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n", "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", "\n", - "\n", "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", @@ -288,49 +332,7 @@ } ], "source": [ - "print(guard.base_prompt)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, `nl_language` is the natural language instruction and will be provided by the user at runtime." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Wrap the LLM API call with `Guard`" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" - ] - } - ], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", - " prompt_params={\n", - " \"nl_instruction\": \"Select the name of the employee who has the highest salary.\"\n", - " },\n", - " max_tokens=2048,\n", - " temperature=0,\n", - ")" + "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])" ] }, { @@ -344,17 +346,17 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
{'generated_sql': 'SELECT name FROM employee ORDER BY salary DESC LIMIT 1'}\n",
+       "
{'generated_sql': 'SELECT name FROM employees ORDER BY salary DESC LIMIT 1;'}\n",
        "
\n" ], "text/plain": [ - "\u001b[1m{\u001b[0m\u001b[32m'generated_sql'\u001b[0m: \u001b[32m'SELECT name FROM employee ORDER BY salary DESC LIMIT 1'\u001b[0m\u001b[1m}\u001b[0m\n" + "\u001b[1m{\u001b[0m\u001b[32m'generated_sql'\u001b[0m: \u001b[32m'SELECT name FROM employees ORDER BY salary DESC LIMIT 1;'\u001b[0m\u001b[1m}\u001b[0m\n" ] }, "metadata": {}, @@ -367,7 +369,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -376,51 +378,53 @@ "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Generate a valid SQL query for the following natural language instruction:                              │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Select the name of the employee who has the highest salary.                                             │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <string name=\"generated_sql\" description=\"Generate SQL for the given natural language instruction.\" │ │\n",
-       "    │ │ format=\"bug-free-sql\"/>                                                                                 │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Generate a valid SQL query for the following natural language instruction:                   │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Select the name of the employee who has the highest salary.                                  │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <string description=\"Generate SQL for the given natural language instruction.\"             │ │ │\n",
+       "    │ │ │      │ format=\"guardrails/valid_sql: None None\" name=\"generated_sql\" required=\"true\"></string>      │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ ```json                                                                                                 │ │\n",
        "    │ │ {                                                                                                       │ │\n",
-       "    │ │   \"generated_sql\": \"SELECT name FROM employee ORDER BY salary DESC LIMIT 1\"                             │ │\n",
+       "    │ │   \"generated_sql\": \"SELECT name FROM employees ORDER BY salary DESC LIMIT 1;\"                           │ │\n",
        "    │ │ }                                                                                                       │ │\n",
+       "    │ │ ```                                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ {'generated_sql': 'SELECT name FROM employee ORDER BY salary DESC LIMIT 1'}                             │ │\n",
+       "    │ │ {'generated_sql': 'SELECT name FROM employees ORDER BY salary DESC LIMIT 1;'}                           │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
        "
\n" @@ -429,51 +433,53 @@ "Logs\n", "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGenerate a valid SQL query for the following natural language instruction:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSelect the name of the employee who has the highest salary.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGenerate a valid SQL query for the following natural language instruction: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mSelect the name of the employee who has the highest salary. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE', \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index': \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"generated_sql\": \"SELECT name FROM employee ORDER BY salary DESC LIMIT 1\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"generated_sql\": \"SELECT name FROM employees ORDER BY salary DESC LIMIT 1;\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'generated_sql': 'SELECT name FROM employee ORDER BY salary DESC LIMIT 1'}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'generated_sql': 'SELECT name FROM employees ORDER BY salary DESC LIMIT 1;'}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] @@ -503,7 +509,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.17" + "version": "3.12.1" }, "orig_nbformat": 4, "vscode": { diff --git a/docs/examples/text_summarization_quality.ipynb b/docs/examples/text_summarization_quality.ipynb index b9c7e59ed..0daf1f509 100644 --- a/docs/examples/text_summarization_quality.ipynb +++ b/docs/examples/text_summarization_quality.ipynb @@ -2,44 +2,11 @@ "cells": [ { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", - "To disable this warning, you can either:\n", - "\t- Avoid using `tokenizers` before the fork if possible\n", - "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95msimilar_to_document...\u001b[0m\n", - "\u001b[2K\u001b[32m[= ]\u001b[0m Fetching manifestst\n", - "\u001b[2K\u001b[32m[== ]\u001b[0m Downloading dependenciespendencies Running command git clone --filter=blob:none --quiet https://github.com/guardrails-ai/similar_to_document.git /private/var/folders/w2/ssf16z690zd7_4dggw0y5s_m0000gn/T/pip-req-build-oys8q6q2\n", - "\u001b[2K\u001b[32m[=== ]\u001b[0m Downloading dependencies\u001b[33mWARNING: Target directory /Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/guardrails/hub/guardrails/similar_to_document/validator already exists. Specify --upgrade to force replacement.\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33mWARNING: Target directory /Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/guardrails/hub/guardrails/similar_to_document/similar_to_document-0.0.0.dist-info already exists. Specify --upgrade to force replacement.\u001b[0m\u001b[33m\n", - "\u001b[2K\u001b[32m[ ==]\u001b[0m Downloading dependencies\n", - "\u001b[1A\u001b[2K\u001b[?25l\u001b[32m[ ]\u001b[0m Running post-install setup\n", - "\u001b[1A\u001b[2K✅Successfully installed guardrails/similar_to_document!\n", - "\n", - "\n", - "\u001b[1mImport validator:\u001b[0m\n", - "from guardrails.hub import SimilarToDocument\n", - "\n", - "\u001b[1mGet more info:\u001b[0m\n", - "\u001b[4;94mhttps://hub.guardrailsai.com/validator/guardrails/similar_to_document\u001b[0m\n", - "\n" - ] - } - ], + "outputs": [], "source": [ - "!guardrails hub install hub://guardrails/similar_to_document" + "!guardrails hub install hub://guardrails/similar_to_document --quiet" ] }, { @@ -49,8 +16,9 @@ "source": [ "# Summarize text accurately\n", "\n", - "!!! note\n", + ":::note\n", " To download this example as a Jupyter notebook, click [here](https://github.com/ShreyaR/guardrails/blob/main/docs/examples/text_summarization_quality.ipynb).\n", + ":::\n", "\n", "In this example, we will use Guardrails in the summarization of a text document. We will check whether the summarized document has a high semantic similarity with the original document.\n", "\n", @@ -69,7 +37,7 @@ "metadata": {}, "outputs": [], "source": [ - "!pip install numpy" + "! pip install numpy -q" ] }, { @@ -95,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -114,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -138,7 +106,7 @@ "\n", "${document}\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\n", "\n", "\"\"\"\n", @@ -167,7 +135,7 @@ "\n", "${document}\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\"\"\"\n", "\n", "\n", @@ -185,9 +153,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "!!! note\n", + ":::note\n", + "\n", + " In order to ensure the summary is similar to the document, we use `similar-to-document` as the validator. This validator embeds the document and the summary and checks whether the cosine similarity between the two embeddings is above a threshold.\n", "\n", - " In order to ensure the summary is similar to the document, we use `similar-to-document` as the validator. This validator embeds the document and the summary and checks whether the cosine similarity between the two embeddings is above a threshold." + ":::" ] }, { @@ -205,7 +175,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -239,135 +209,11 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading the model all-MiniLM-L6-v2. This may take a while...\n" - ] - } - ], - "source": [ - "guard = gd.Guard.from_pydantic(output_class=DocumentSummary, prompt=prompt)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We see the prompt that will be sent to the LLM:" - ] - }, - { - "cell_type": "code", - "execution_count": 27, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n",
-       "Summarize the following document:\n",
-       "\n",
-       "${document}\n",
-       "\n",
-       "\n",
-       "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
-       "\n",
-       "<output>\n",
-       "    <string name=\"summary\" description=\"Summarize the given document faithfully.\" \n",
-       "format=\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted shall be vested \n",
-       "in a Congress of the United States, which shall consist of a Senate and House of Representatives.Section. 2.The \n",
-       "House of Representatives shall be composed of Members chosen every second Year by the People of the several States,\n",
-       "and the Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch of \n",
-       "the State Legislature.No Person shall be a Representative who shall not have attained to the Age of twenty five \n",
-       "Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of \n",
-       "that State in which he shall be chosen.Representatives and direct Taxes shall be apportioned among the several \n",
-       "States which may be included within this Union, according to their respective Numbers, which shall be determined by\n",
-       "adding to the whole Number of free Persons, including those bound to Service for a Term of Years, and excluding \n",
-       "Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three Years after\n",
-       "the first Meeting of the Congress of the United States, and within every subsequent Term of ten Years, in such \n",
-       "Manner as they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, \n",
-       "but each State shall have at Least one Representative; and until such enumeration shall be made, the State of New \n",
-       "Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, \n",
-       "Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, \n",
-       "North Carolina five, South Carolina five, and Georgia three.When vacancies happen in the Representation from any \n",
-       "State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies.The House of \n",
-       "Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of Impeachment.' \n",
-       "threshold=0.6 model=all-MiniLM-L6-v2\"/>\n",
-       "</output>\n",
-       "\n",
-       "\n",
-       "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n",
-       "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n",
-       "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n",
-       "specific types. Be correct and concise. If you are unsure anywhere, enter `null`.\n",
-       "\n",
-       "Here are examples of simple (XML, JSON) pairs that show the expected behavior:\n",
-       "- `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`\n",
-       "- `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO', etc.]}`\n",
-       "- `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\" format=\"1-indexed\" \n",
-       "/></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`\n",
-       "\n",
-       "\n",
-       "
\n" - ], - "text/plain": [ - "\n", - "Summarize the following document:\n", - "\n", - "$\u001b[1m{\u001b[0mdocument\u001b[1m}\u001b[0m\n", - "\n", - "\n", - "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n", - "\n", - "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\u001b[39m \u001b[0m\n", - "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n", - "\n", - "\n", - "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n", - "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n", - "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n", - "\u001b[39mspecific types. Be correct and concise. If you are unsure anywhere, enter `null`.\u001b[0m\n", - "\n", - "\u001b[39mHere are examples of simple \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mXML, JSON\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m pairs that show the expected behavior:\u001b[0m\n", - "\u001b[39m- `` => `\u001b[0m\u001b[1;39m{\u001b[0m\u001b[32m'foo'\u001b[0m\u001b[39m: \u001b[0m\u001b[32m'example one'\u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m`\u001b[0m\n", - "\u001b[39m- `<\u001b[0m\u001b[35m/\u001b[0m\u001b[95mlist\u001b[0m\u001b[39m>` => `\u001b[0m\u001b[1;39m{\u001b[0m\u001b[32m\"bar\"\u001b[0m\u001b[39m: \u001b[0m\u001b[1;39m[\u001b[0m\u001b[32m'STRING ONE'\u001b[0m\u001b[39m, \u001b[0m\u001b[32m'STRING TWO'\u001b[0m\u001b[39m, etc.\u001b[0m\u001b[1;39m]\u001b[0m\u001b[1;39m}\u001b[0m\u001b[39m`\u001b[0m\n", - "\u001b[39m- `<\u001b[0m\u001b[35m/\u001b[0m\u001b[95mobject\u001b[0m\u001b[39m>` =\u001b[0m\u001b[1m>\u001b[0m `\u001b[1m{\u001b[0m\u001b[32m'baz'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'foo'\u001b[0m: \u001b[32m'Some String'\u001b[0m, \u001b[32m'index'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m`\n", - "\n", - "\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "print(guard.rail.prompt)" + "guard = gd.Guard.from_pydantic(output_class=DocumentSummary)" ] }, { @@ -393,69 +239,16 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Similarity: 0.971, Type: \n" - ] - }, - { - "data": { - "text/html": [ - "
Validated Output: {'summary': 'All legislative Powers herein granted shall be vested in a Congress of the United \n",
-       "States, which shall consist of a Senate and House of Representatives. The House of Representatives shall be \n",
-       "composed of Members chosen every second Year by the People of the several States, and the Electors in each State \n",
-       "shall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No \n",
-       "Person shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years \n",
-       "a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall \n",
-       "be chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included \n",
-       "within this Union, according to their respective Numbers, which shall be determined by adding to the whole Number \n",
-       "of free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three \n",
-       "fifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the\n",
-       "Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law \n",
-       "direct. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at \n",
-       "Least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to\n",
-       "chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New \n",
-       "Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina \n",
-       "five, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority \n",
-       "thereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their \n",
-       "Speaker and other Officers; and shall have the sole Power of Impeachment.'}\n",
-       "
\n" - ], - "text/plain": [ - "Validated Output: \u001b[1m{\u001b[0m\u001b[32m'summary'\u001b[0m: \u001b[32m'All legislative Powers herein granted shall be vested in a Congress of the United \u001b[0m\n", - "\u001b[32mStates, which shall consist of a Senate and House of Representatives. The House of Representatives shall be \u001b[0m\n", - "\u001b[32mcomposed of Members chosen every second Year by the People of the several States, and the Electors in each State \u001b[0m\n", - "\u001b[32mshall have the Qualifications requisite for Electors of the most numerous Branch of the State Legislature. No \u001b[0m\n", - "\u001b[32mPerson shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven Years \u001b[0m\n", - "\u001b[32ma Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State in which he shall \u001b[0m\n", - "\u001b[32mbe chosen. Representatives and direct Taxes shall be apportioned among the several States which may be included \u001b[0m\n", - "\u001b[32mwithin this Union, according to their respective Numbers, which shall be determined by adding to the whole Number \u001b[0m\n", - "\u001b[32mof free Persons, including those bound to Service for a Term of Years, and excluding Indians not taxed, three \u001b[0m\n", - "\u001b[32mfifths of all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of the\u001b[0m\n", - "\u001b[32mCongress of the United States, and within every subsequent Term of ten Years, in such Manner as they shall by Law \u001b[0m\n", - "\u001b[32mdirect. The Number of Representatives shall not exceed one for every thirty Thousand, but each State shall have at \u001b[0m\n", - "\u001b[32mLeast one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to\u001b[0m\n", - "\u001b[32mchuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New \u001b[0m\n", - "\u001b[32mJersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina \u001b[0m\n", - "\u001b[32mfive, and Georgia three. When vacancies happen in the Representation from any State, the Executive Authority \u001b[0m\n", - "\u001b[32mthereof shall issue Writs of Election to fill such Vacancies. The House of Representatives shall chuse their \u001b[0m\n", - "\u001b[32mSpeaker and other Officers; and shall have the sole Power of Impeachment.'\u001b[0m\u001b[1m}\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "import openai\n", + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", "\n", "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", " prompt_params={\"document\": document},\n", " model=\"gpt-3.5-turbo\",\n", " max_tokens=2048,\n", @@ -465,6 +258,22 @@ "print(f\"Validated Output: {validated_response}\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see the prompt that was sent to the LLM:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])" + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -475,293 +284,9 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Summarize the following document:                                                                       │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Section. 1.                                                                                             │ │\n",
-       "    │ │ All legislative Powers herein granted shall be vested in a Congress of the United States, which shall   │ │\n",
-       "    │ │ consist of a Senate and House of Representatives.                                                       │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Section. 2.                                                                                             │ │\n",
-       "    │ │ The House of Representatives shall be composed of Members chosen every second Year by the People of the │ │\n",
-       "    │ │ several States, and the Electors in each State shall have the Qualifications requisite for Electors of  │ │\n",
-       "    │ │ the most numerous Branch of the State Legislature.                                                      │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and    │ │\n",
-       "    │ │ been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of   │ │\n",
-       "    │ │ that State in which he shall be chosen.                                                                 │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Representatives and direct Taxes shall be apportioned among the several States which may be included    │ │\n",
-       "    │ │ within this Union, according to their respective Numbers, which shall be determined by adding to the    │ │\n",
-       "    │ │ whole Number of free Persons, including those bound to Service for a Term of Years, and excluding       │ │\n",
-       "    │ │ Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three │ │\n",
-       "    │ │ Years after the first Meeting of the Congress of the United States, and within every subsequent Term of │ │\n",
-       "    │ │ ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed   │ │\n",
-       "    │ │ one for every thirty Thousand, but each State shall have at Least one Representative; and until such    │ │\n",
-       "    │ │ enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts   │ │\n",
-       "    │ │ eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four,    │ │\n",
-       "    │ │ Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, │ │\n",
-       "    │ │ and Georgia three.                                                                                      │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue │ │\n",
-       "    │ │ Writs of Election to fill such Vacancies.                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole      │ │\n",
-       "    │ │ Power of Impeachment.                                                                                   │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <string name=\"summary\" description=\"Summarize the given document faithfully.\"                       │ │\n",
-       "    │ │ format=\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted      │ │\n",
-       "    │ │ shall be vested in a Congress of the United States, which shall consist of a Senate and House of        │ │\n",
-       "    │ │ Representatives.Section. 2.The House of Representatives shall be composed of Members chosen every       │ │\n",
-       "    │ │ second Year by the People of the several States, and the Electors in each State shall have the          │ │\n",
-       "    │ │ Qualifications requisite for Electors of the most numerous Branch of the State Legislature.No Person    │ │\n",
-       "    │ │ shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven   │ │\n",
-       "    │ │ Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State   │ │\n",
-       "    │ │ in which he shall be chosen.Representatives and direct Taxes shall be apportioned among the several     │ │\n",
-       "    │ │ States which may be included within this Union, according to their respective Numbers, which shall be   │ │\n",
-       "    │ │ determined by adding to the whole Number of free Persons, including those bound to Service for a Term   │ │\n",
-       "    │ │ of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration    │ │\n",
-       "    │ │ shall be made within three Years after the first Meeting of the Congress of the United States, and      │ │\n",
-       "    │ │ within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of    │ │\n",
-       "    │ │ Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one  │ │\n",
-       "    │ │ Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled  │ │\n",
-       "    │ │ to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five,     │ │\n",
-       "    │ │ New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North      │ │\n",
-       "    │ │ Carolina five, South Carolina five, and Georgia three.When vacancies happen in the Representation from  │ │\n",
-       "    │ │ any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies.The     │ │\n",
-       "    │ │ House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of │ │\n",
-       "    │ │ Impeachment.' threshold=0.6 model=all-MiniLM-L6-v2\"/>                                                   │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ {\"summary\":\"All legislative Powers herein granted shall be vested in a Congress of the United States,   │ │\n",
-       "    │ │ which shall consist of a Senate and House of Representatives. The House of Representatives shall be     │ │\n",
-       "    │ │ composed of Members chosen every second Year by the People of the several States, and the Electors in   │ │\n",
-       "    │ │ each State shall have the Qualifications requisite for Electors of the most numerous Branch of the      │ │\n",
-       "    │ │ State Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty │ │\n",
-       "    │ │ five Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an │ │\n",
-       "    │ │ Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be         │ │\n",
-       "    │ │ apportioned among the several States which may be included within this Union, according to their        │ │\n",
-       "    │ │ respective Numbers, which shall be determined by adding to the whole Number of free Persons, including  │ │\n",
-       "    │ │ those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other  │ │\n",
-       "    │ │ Persons. The actual Enumeration shall be made within three Years after the first Meeting of the         │ │\n",
-       "    │ │ Congress of the United States, and within every subsequent Term of ten Years, in such Manner as they    │ │\n",
-       "    │ │ shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but  │ │\n",
-       "    │ │ each State shall have at Least one Representative; and until such enumeration shall be made, the State  │ │\n",
-       "    │ │ of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence     │ │\n",
-       "    │ │ Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one,     │ │\n",
-       "    │ │ Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies │ │\n",
-       "    │ │ happen in the Representation from any State, the Executive Authority thereof shall issue Writs of       │ │\n",
-       "    │ │ Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and other       │ │\n",
-       "    │ │ Officers; and shall have the sole Power of Impeachment.\"}                                               │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ {                                                                                                       │ │\n",
-       "    │ │     'summary': 'All legislative Powers herein granted shall be vested in a Congress of the United       │ │\n",
-       "    │ │ States, which shall consist of a Senate and House of Representatives. The House of Representatives      │ │\n",
-       "    │ │ shall be composed of Members chosen every second Year by the People of the several States, and the      │ │\n",
-       "    │ │ Electors in each State shall have the Qualifications requisite for Electors of the most numerous Branch │ │\n",
-       "    │ │ of the State Legislature. No Person shall be a Representative who shall not have attained to the Age of │ │\n",
-       "    │ │ twenty five Years, and been seven Years a Citizen of the United States, and who shall not, when         │ │\n",
-       "    │ │ elected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes   │ │\n",
-       "    │ │ shall be apportioned among the several States which may be included within this Union, according to     │ │\n",
-       "    │ │ their respective Numbers, which shall be determined by adding to the whole Number of free Persons,      │ │\n",
-       "    │ │ including those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of  │ │\n",
-       "    │ │ all other Persons. The actual Enumeration shall be made within three Years after the first Meeting of   │ │\n",
-       "    │ │ the Congress of the United States, and within every subsequent Term of ten Years, in such Manner as     │ │\n",
-       "    │ │ they shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, │ │\n",
-       "    │ │ but each State shall have at Least one Representative; and until such enumeration shall be made, the    │ │\n",
-       "    │ │ State of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and          │ │\n",
-       "    │ │ Providence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight,        │ │\n",
-       "    │ │ Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three.  │ │\n",
-       "    │ │ When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue │ │\n",
-       "    │ │ Writs of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and    │ │\n",
-       "    │ │ other Officers; and shall have the sole Power of Impeachment.'                                          │ │\n",
-       "    │ │ }                                                                                                       │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "
\n" - ], - "text/plain": [ - "Logs\n", - "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", - " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSummarize the following document:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSection. 1.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAll legislative Powers herein granted shall be vested in a Congress of the United States, which shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mconsist of a Senate and House of Representatives.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSection. 2.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mThe House of Representatives shall be composed of Members chosen every second Year by the People of the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mseveral States, and the Electors in each State shall have the Qualifications requisite for Electors of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthe most numerous Branch of the State Legislature.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo Person shall be a Representative who shall not have attained to the Age of twenty five Years, and \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbeen seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthat State in which he shall be chosen.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRepresentatives and direct Taxes shall be apportioned among the several States which may be included \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwithin this Union, according to their respective Numbers, which shall be determined by adding to the \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwhole Number of free Persons, including those bound to Service for a Term of Years, and excluding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIndians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYears after the first Meeting of the Congress of the United States, and within every subsequent Term of\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mone for every thirty Thousand, but each State shall have at Least one Representative; and until such \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255meight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five,\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mand Georgia three.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWhen vacancies happen in the Representation from any State, the Executive Authority thereof shall issue\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWrits of Election to fill such Vacancies.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mThe House of Representatives shall chuse their Speaker and other Officers; and shall have the sole \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPower of Impeachment.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\"summary\":\"All legislative Powers herein granted shall be vested in a Congress of the United States, \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mwhich shall consist of a Senate and House of Representatives. The House of Representatives shall be \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mcomposed of Members chosen every second Year by the People of the several States, and the Electors in \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220meach State shall have the Qualifications requisite for Electors of the most numerous Branch of the \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mState Legislature. No Person shall be a Representative who shall not have attained to the Age of twenty\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mfive Years, and been seven Years a Citizen of the United States, and who shall not, when elected, be an\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mInhabitant of that State in which he shall be chosen. Representatives and direct Taxes shall be \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mapportioned among the several States which may be included within this Union, according to their \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mrespective Numbers, which shall be determined by adding to the whole Number of free Persons, including \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthose bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of all other \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPersons. The actual Enumeration shall be made within three Years after the first Meeting of the \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mCongress of the United States, and within every subsequent Term of ten Years, in such Manner as they \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mshall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand, but \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220meach State shall have at Least one Representative; and until such enumeration shall be made, the State \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and Providence \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPlantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, Delaware one, \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mMaryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. When vacancies\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mhappen in the Representation from any State, the Executive Authority thereof shall issue Writs of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mElection to fill such Vacancies. The House of Representatives shall chuse their Speaker and other \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mOfficers; and shall have the sole Power of Impeachment.\"}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m 'summary': 'All legislative Powers herein granted shall be vested in a Congress of the United \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mStates, which shall consist of a Senate and House of Representatives. The House of Representatives \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mshall be composed of Members chosen every second Year by the People of the several States, and the \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mElectors in each State shall have the Qualifications requisite for Electors of the most numerous Branch\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mof the State Legislature. No Person shall be a Representative who shall not have attained to the Age of\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtwenty five Years, and been seven Years a Citizen of the United States, and who shall not, when \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240melected, be an Inhabitant of that State in which he shall be chosen. Representatives and direct Taxes \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mshall be apportioned among the several States which may be included within this Union, according to \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mtheir respective Numbers, which shall be determined by adding to the whole Number of free Persons, \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mincluding those bound to Service for a Term of Years, and excluding Indians not taxed, three fifths of \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mall other Persons. The actual Enumeration shall be made within three Years after the first Meeting of \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mthe Congress of the United States, and within every subsequent Term of ten Years, in such Manner as \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mthey shall by Law direct. The Number of Representatives shall not exceed one for every thirty Thousand,\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mbut each State shall have at Least one Representative; and until such enumeration shall be made, the \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mState of New Hampshire shall be entitled to chuse three, Massachusetts eight, Rhode-Island and \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mProvidence Plantations one, Connecticut five, New-York six, New Jersey four, Pennsylvania eight, \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mDelaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mWhen vacancies happen in the Representation from any State, the Executive Authority thereof shall issue\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mWrits of Election to fill such Vacancies. The House of Representatives shall chuse their Speaker and \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mother Officers; and shall have the sole Power of Impeachment.'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "print(guard.history.last.tree)" ] @@ -778,26 +303,12 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Validated Output: None\n",
-       "
\n" - ], - "text/plain": [ - "Validated Output: \u001b[3;35mNone\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "raw_llm_response, validated_response, *rest = guard(\n", - " openai.completions.create,\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", " prompt_params={\"document\": open(\"data/article1.txt\", \"r\").read()},\n", " model=\"babbage-002\",\n", " max_tokens=512,\n", @@ -817,585 +328,9 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Logs\n",
-       "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "│   │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Summarize the following document:                                                                       │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Section. 1.                                                                                             │ │\n",
-       "│   │ │ All legislative Powers herein granted shall be vested in a Congress of the United States, which shall   │ │\n",
-       "│   │ │ consist of a Senate and House of Representatives.                                                       │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Section. 2.                                                                                             │ │\n",
-       "│   │ │ The House of Representatives shall be composed of Members chosen every second Year by the People of the │ │\n",
-       "│   │ │ several States, and the Electors in each State shall have the Qualifications requisite for Electors of  │ │\n",
-       "│   │ │ the most numerous Branch of the State Legislature.                                                      │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ No Person shall be a Representative who shall not have attained to the Age of twenty five Years, and    │ │\n",
-       "│   │ │ been seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of   │ │\n",
-       "│   │ │ that State in which he shall be chosen.                                                                 │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Representatives and direct Taxes shall be apportioned among the several States which may be included    │ │\n",
-       "│   │ │ within this Union, according to their respective Numbers, which shall be determined by adding to the    │ │\n",
-       "│   │ │ whole Number of free Persons, including those bound to Service for a Term of Years, and excluding       │ │\n",
-       "│   │ │ Indians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three │ │\n",
-       "│   │ │ Years after the first Meeting of the Congress of the United States, and within every subsequent Term of │ │\n",
-       "│   │ │ ten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed   │ │\n",
-       "│   │ │ one for every thirty Thousand, but each State shall have at Least one Representative; and until such    │ │\n",
-       "│   │ │ enumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts   │ │\n",
-       "│   │ │ eight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four,    │ │\n",
-       "│   │ │ Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, │ │\n",
-       "│   │ │ and Georgia three.                                                                                      │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ When vacancies happen in the Representation from any State, the Executive Authority thereof shall issue │ │\n",
-       "│   │ │ Writs of Election to fill such Vacancies.                                                               │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ The House of Representatives shall chuse their Speaker and other Officers; and shall have the sole      │ │\n",
-       "│   │ │ Power of Impeachment.                                                                                   │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "│   │ │ it into.                                                                                                │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ <output>                                                                                                │ │\n",
-       "│   │ │     <string name=\"summary\" description=\"Summarize the given document faithfully.\"                       │ │\n",
-       "│   │ │ format=\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted      │ │\n",
-       "│   │ │ shall be vested in a Congress of the United States, which shall consist of a Senate and House of        │ │\n",
-       "│   │ │ Representatives.Section. 2.The House of Representatives shall be composed of Members chosen every       │ │\n",
-       "│   │ │ second Year by the People of the several States, and the Electors in each State shall have the          │ │\n",
-       "│   │ │ Qualifications requisite for Electors of the most numerous Branch of the State Legislature.No Person    │ │\n",
-       "│   │ │ shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven   │ │\n",
-       "│   │ │ Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State   │ │\n",
-       "│   │ │ in which he shall be chosen.Representatives and direct Taxes shall be apportioned among the several     │ │\n",
-       "│   │ │ States which may be included within this Union, according to their respective Numbers, which shall be   │ │\n",
-       "│   │ │ determined by adding to the whole Number of free Persons, including those bound to Service for a Term   │ │\n",
-       "│   │ │ of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration    │ │\n",
-       "│   │ │ shall be made within three Years after the first Meeting of the Congress of the United States, and      │ │\n",
-       "│   │ │ within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of    │ │\n",
-       "│   │ │ Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one  │ │\n",
-       "│   │ │ Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled  │ │\n",
-       "│   │ │ to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five,     │ │\n",
-       "│   │ │ New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North      │ │\n",
-       "│   │ │ Carolina five, South Carolina five, and Georgia three.When vacancies happen in the Representation from  │ │\n",
-       "│   │ │ any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies.The     │ │\n",
-       "│   │ │ House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of │ │\n",
-       "│   │ │ Impeachment.' threshold=0.6 model=all-MiniLM-L6-v2\"/>                                                   │ │\n",
-       "│   │ │ </output>                                                                                               │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "│   │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "│   │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "│   │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "│   │ │ enter `null`.                                                                                           │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "│   │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "│   │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "│   │ │ etc.]}`                                                                                                 │ │\n",
-       "│   │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "│   │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ Json Output:                                                                                            │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "│   │ │ No message history.                                                                                     │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "│   │ │     {                                                                                                   │ │\n",
-       "│   │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "│   │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "│   │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "│   │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "│   │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "│   │ │ of Representatives.',                                                                                   │ │\n",
-       "│   │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "│   │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "│   │ │         \"model\": \"all-MiniLM-L6-v2\"                                                                     │ │\n",
-       "│   │ │     }                                                                                                   │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ JSON Output:                                                                                            │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │     {                                                                                                   │ │\n",
-       "│   │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "│   │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "│   │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "│   │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "│   │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "│   │ │ of Representatives.',                                                                                   │ │\n",
-       "│   │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "│   │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "│   │ │         \"model\": \"all-MiniLM-L6-v2\"                                                                     │ │\n",
-       "│   │ │     }                                                                                                   │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ JSON Output:                                                                                            │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │     {                                                                                                   │ │\n",
-       "│   │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "│   │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "│   │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "│   │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "│   │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "│   │ │ of Representatives.',                                                                                   │ │\n",
-       "│   │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "│   │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "│   │ │         \"model\": \"all-MiniLM-L6-v2\"                                                                     │ │\n",
-       "│   │ │     }                                                                                                   │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │ JSON Output:                                                                                            │ │\n",
-       "│   │ │                                                                                                         │ │\n",
-       "│   │ │     {                                                                                                   │ │\n",
-       "│   │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "│   │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "│   │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "│   │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "│   │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "│   │ │ of Representatives.',                                                                                   │ │\n",
-       "│   │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "│   │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "│   │ │         \"model\": \"all-M                                                                                 │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "│   │ │ None                                                                                                    │ │\n",
-       "│   │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "│   ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
-       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ I was given the following response, which was not parseable as JSON.                                    │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ \"    {\\n        \\\"summary\\\": \\\"Summarize the given document faithfully.\\\",\\n        \\\"string\\\":         │ │\n",
-       "    │ │ \\\"Section. 1.All legislative Powers herein granted shall be vested in a Congress of the United States,  │ │\n",
-       "    │ │ which shall consist of a Senate and House of Representatives.\\\",\\n        \\\"format\\\":                   │ │\n",
-       "    │ │ \\\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted shall be   │ │\n",
-       "    │ │ vested in a Congress of the United States, which shall consist of a Senate and House of                 │ │\n",
-       "    │ │ Representatives.',\\n        \\\"name\\\": \\\"summary\\\",\\n        \\\"threshold\\\": 0.6,\\n        \\\"model\\\":     │ │\n",
-       "    │ │ \\\"all-MiniLM-L6-v2\\\"\\n    }\\n\\nJSON Output:\\n\\n    {\\n        \\\"summary\\\": \\\"Summarize the given        │ │\n",
-       "    │ │ document faithfully.\\\",\\n        \\\"string\\\": \\\"Section. 1.All legislative Powers herein granted shall   │ │\n",
-       "    │ │ be vested in a Congress of the United States, which shall consist of a Senate and House of              │ │\n",
-       "    │ │ Representatives.\\\",\\n        \\\"format\\\": \\\"guardrails/similar_to_document: document='Section. 1.All     │ │\n",
-       "    │ │ legislative Powers herein granted shall be vested in a Congress of the United States, which shall       │ │\n",
-       "    │ │ consist of a Senate and House of Representatives.',\\n        \\\"name\\\": \\\"summary\\\",\\n                   │ │\n",
-       "    │ │ \\\"threshold\\\": 0.6,\\n        \\\"model\\\": \\\"all-MiniLM-L6-v2\\\"\\n    }\\n\\nJSON Output:\\n\\n    {\\n          │ │\n",
-       "    │ │ \\\"summary\\\": \\\"Summarize the given document faithfully.\\\",\\n        \\\"string\\\": \\\"Section. 1.All        │ │\n",
-       "    │ │ legislative Powers herein granted shall be vested in a Congress of the United States, which shall       │ │\n",
-       "    │ │ consist of a Senate and House of Representatives.\\\",\\n        \\\"format\\\":                               │ │\n",
-       "    │ │ \\\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted shall be   │ │\n",
-       "    │ │ vested in a Congress of the United States, which shall consist of a Senate and House of                 │ │\n",
-       "    │ │ Representatives.',\\n        \\\"name\\\": \\\"summary\\\",\\n        \\\"threshold\\\": 0.6,\\n        \\\"model\\\":     │ │\n",
-       "    │ │ \\\"all-MiniLM-L6-v2\\\"\\n    }\\n\\nJSON Output:\\n\\n    {\\n        \\\"summary\\\": \\\"Summarize the given        │ │\n",
-       "    │ │ document faithfully.\\\",\\n        \\\"string\\\": \\\"Section. 1.All legislative Powers herein granted shall   │ │\n",
-       "    │ │ be vested in a Congress of the United States, which shall consist of a Senate and House of              │ │\n",
-       "    │ │ Representatives.\\\",\\n        \\\"format\\\": \\\"guardrails/similar_to_document: document='Section. 1.All     │ │\n",
-       "    │ │ legislative Powers herein granted shall be vested in a Congress of the United States, which shall       │ │\n",
-       "    │ │ consist of a Senate and House of Representatives.',\\n        \\\"name\\\": \\\"summary\\\",\\n                   │ │\n",
-       "    │ │ \\\"threshold\\\": 0.6,\\n        \\\"model\\\": \\\"all-M\"                                                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Help me correct this by making it valid JSON.                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <string name=\"summary\" description=\"Summarize the given document faithfully.\"                       │ │\n",
-       "    │ │ format=\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted      │ │\n",
-       "    │ │ shall be vested in a Congress of the United States, which shall consist of a Senate and House of        │ │\n",
-       "    │ │ Representatives.Section. 2.The House of Representatives shall be composed of Members chosen every       │ │\n",
-       "    │ │ second Year by the People of the several States, and the Electors in each State shall have the          │ │\n",
-       "    │ │ Qualifications requisite for Electors of the most numerous Branch of the State Legislature.No Person    │ │\n",
-       "    │ │ shall be a Representative who shall not have attained to the Age of twenty five Years, and been seven   │ │\n",
-       "    │ │ Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of that State   │ │\n",
-       "    │ │ in which he shall be chosen.Representatives and direct Taxes shall be apportioned among the several     │ │\n",
-       "    │ │ States which may be included within this Union, according to their respective Numbers, which shall be   │ │\n",
-       "    │ │ determined by adding to the whole Number of free Persons, including those bound to Service for a Term   │ │\n",
-       "    │ │ of Years, and excluding Indians not taxed, three fifths of all other Persons. The actual Enumeration    │ │\n",
-       "    │ │ shall be made within three Years after the first Meeting of the Congress of the United States, and      │ │\n",
-       "    │ │ within every subsequent Term of ten Years, in such Manner as they shall by Law direct. The Number of    │ │\n",
-       "    │ │ Representatives shall not exceed one for every thirty Thousand, but each State shall have at Least one  │ │\n",
-       "    │ │ Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled  │ │\n",
-       "    │ │ to chuse three, Massachusetts eight, Rhode-Island and Providence Plantations one, Connecticut five,     │ │\n",
-       "    │ │ New-York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North      │ │\n",
-       "    │ │ Carolina five, South Carolina five, and Georgia three.When vacancies happen in the Representation from  │ │\n",
-       "    │ │ any State, the Executive Authority thereof shall issue Writs of Election to fill such Vacancies.The     │ │\n",
-       "    │ │ House of Representatives shall chuse their Speaker and other Officers; and shall have the sole Power of │ │\n",
-       "    │ │ Impeachment.' threshold=0.6 model=all-MiniLM-L6-v2\"/>                                                   │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Json Output:                                                                                            │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "    │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "    │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "    │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "    │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "    │ │ of Representatives.',                                                                                   │ │\n",
-       "    │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "    │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "    │ │         \"model\": \"all-MiniLM-L6-v2\"                                                                     │ │\n",
-       "    │ │     }                                                                                                   │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ JSON Output:                                                                                            │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "    │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "    │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "    │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "    │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "    │ │ of Representatives.',                                                                                   │ │\n",
-       "    │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "    │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "    │ │         \"model\": \"all-MiniLM-L6-v2\"                                                                     │ │\n",
-       "    │ │     }                                                                                                   │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ JSON Output:                                                                                            │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "    │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "    │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "    │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "    │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "    │ │ of Representatives.',                                                                                   │ │\n",
-       "    │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "    │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "    │ │         \"model\": \"all-MiniLM-L6-v2\"                                                                     │ │\n",
-       "    │ │     }                                                                                                   │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ JSON Output:                                                                                            │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │     {                                                                                                   │ │\n",
-       "    │ │         \"summary\": \"Summarize the given document faithfully.\",                                          │ │\n",
-       "    │ │         \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of    │ │\n",
-       "    │ │ the United States, which shall consist of a Senate and House of Representatives.\",                      │ │\n",
-       "    │ │         \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein   │ │\n",
-       "    │ │ granted shall be vested in a Congress of the United States, which shall consist of a Senate and House   │ │\n",
-       "    │ │ of Representatives.',                                                                                   │ │\n",
-       "    │ │         \"name\": \"summary\",                                                                              │ │\n",
-       "    │ │         \"threshold\": 0.6,                                                                               │ │\n",
-       "    │ │         \"model\": \"all-M                                                                                 │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ None                                                                                                    │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "
\n" - ], - "text/plain": [ - "Logs\n", - "├── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", - "│ │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSummarize the following document:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSection. 1.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mAll legislative Powers herein granted shall be vested in a Congress of the United States, which shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mconsist of a Senate and House of Representatives.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mSection. 2.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mThe House of Representatives shall be composed of Members chosen every second Year by the People of the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mseveral States, and the Electors in each State shall have the Qualifications requisite for Electors of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthe most numerous Branch of the State Legislature.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo Person shall be a Representative who shall not have attained to the Age of twenty five Years, and \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbeen seven Years a Citizen of the United States, and who shall not, when elected, be an Inhabitant of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mthat State in which he shall be chosen.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRepresentatives and direct Taxes shall be apportioned among the several States which may be included \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwithin this Union, according to their respective Numbers, which shall be determined by adding to the \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwhole Number of free Persons, including those bound to Service for a Term of Years, and excluding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIndians not taxed, three fifths of all other Persons. The actual Enumeration shall be made within three\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mYears after the first Meeting of the Congress of the United States, and within every subsequent Term of\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mten Years, in such Manner as they shall by Law direct. The Number of Representatives shall not exceed \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mone for every thirty Thousand, but each State shall have at Least one Representative; and until such \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menumeration shall be made, the State of New Hampshire shall be entitled to chuse three, Massachusetts \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255meight, Rhode-Island and Providence Plantations one, Connecticut five, New-York six, New Jersey four, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five,\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mand Georgia three.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWhen vacancies happen in the Representation from any State, the Executive Authority thereof shall issue\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mWrits of Election to fill such Vacancies.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mThe House of Representatives shall chuse their Speaker and other Officers; and shall have the sole \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mPower of Impeachment.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mJson Output:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - "│ │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - "│ │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", - "│ │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-MiniLM-L6-v2\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJSON Output:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-MiniLM-L6-v2\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJSON Output:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-MiniLM-L6-v2\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJSON Output:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-M\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - "│ │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - "│ │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mNone\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - "│ │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - "│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n", - "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n", - " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mI was given the following response, which was not parseable as JSON.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\" {\\n \\\"summary\\\": \\\"Summarize the given document faithfully.\\\",\\n \\\"string\\\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"Section. 1.All legislative Powers herein granted shall be vested in a Congress of the United States, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mwhich shall consist of a Senate and House of Representatives.\\\",\\n \\\"format\\\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted shall be \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mvested in a Congress of the United States, which shall consist of a Senate and House of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRepresentatives.',\\n \\\"name\\\": \\\"summary\\\",\\n \\\"threshold\\\": 0.6,\\n \\\"model\\\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"all-MiniLM-L6-v2\\\"\\n }\\n\\nJSON Output:\\n\\n {\\n \\\"summary\\\": \\\"Summarize the given \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdocument faithfully.\\\",\\n \\\"string\\\": \\\"Section. 1.All legislative Powers herein granted shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbe vested in a Congress of the United States, which shall consist of a Senate and House of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRepresentatives.\\\",\\n \\\"format\\\": \\\"guardrails/similar_to_document: document='Section. 1.All \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mlegislative Powers herein granted shall be vested in a Congress of the United States, which shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mconsist of a Senate and House of Representatives.',\\n \\\"name\\\": \\\"summary\\\",\\n \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"threshold\\\": 0.6,\\n \\\"model\\\": \\\"all-MiniLM-L6-v2\\\"\\n }\\n\\nJSON Output:\\n\\n {\\n \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"summary\\\": \\\"Summarize the given document faithfully.\\\",\\n \\\"string\\\": \\\"Section. 1.All \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mlegislative Powers herein granted shall be vested in a Congress of the United States, which shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mconsist of a Senate and House of Representatives.\\\",\\n \\\"format\\\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein granted shall be \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mvested in a Congress of the United States, which shall consist of a Senate and House of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRepresentatives.',\\n \\\"name\\\": \\\"summary\\\",\\n \\\"threshold\\\": 0.6,\\n \\\"model\\\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"all-MiniLM-L6-v2\\\"\\n }\\n\\nJSON Output:\\n\\n {\\n \\\"summary\\\": \\\"Summarize the given \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mdocument faithfully.\\\",\\n \\\"string\\\": \\\"Section. 1.All legislative Powers herein granted shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mbe vested in a Congress of the United States, which shall consist of a Senate and House of \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mRepresentatives.\\\",\\n \\\"format\\\": \\\"guardrails/similar_to_document: document='Section. 1.All \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mlegislative Powers herein granted shall be vested in a Congress of the United States, which shall \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mconsist of a Senate and House of Representatives.',\\n \\\"name\\\": \\\"summary\\\",\\n \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\\\"threshold\\\": 0.6,\\n \\\"model\\\": \\\"all-M\"\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHelp me correct this by making it valid JSON.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mJson Output:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-MiniLM-L6-v2\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJSON Output:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-MiniLM-L6-v2\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJSON Output:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-MiniLM-L6-v2\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m }\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mJSON Output:\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m {\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"summary\": \"Summarize the given document faithfully.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"string\": \"Section. 1.All legislative Powers herein granted shall be vested in a Congress of \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mthe United States, which shall consist of a Senate and House of Representatives.\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"format\": \"guardrails/similar_to_document: document='Section. 1.All legislative Powers herein \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mgranted shall be vested in a Congress of the United States, which shall consist of a Senate and House \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mof Representatives.',\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"name\": \"summary\",\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"threshold\": 0.6,\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"model\": \"all-M\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mNone\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "print(guard.history.last.tree)" ] @@ -1417,7 +352,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.12.1" }, "orig_nbformat": 4 }, diff --git a/docs/examples/toxic_language.ipynb b/docs/examples/toxic_language.ipynb index 78dbe51e9..b5b0fb36c 100644 --- a/docs/examples/toxic_language.ipynb +++ b/docs/examples/toxic_language.ipynb @@ -2,11 +2,24 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95mtoxic_language...\u001b[0m\n", + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n", + "✅Successfully installed guardrails/toxic_language!\n", + "\n", + "\n" + ] + } + ], "source": [ - "!guardrails hub install hub://guardrails/toxic_language" + "! guardrails hub install hub://guardrails/toxic_language --quiet" ] }, { @@ -22,7 +35,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -38,7 +51,16 @@ "cell_type": "code", "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + " warnings.warn(\n" + ] + } + ], "source": [ "# Create a Guard object with this validator\n", "# Here, we'll use the default validation method of \"sentence\"\n", @@ -208,7 +230,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.17" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/docs/examples/translation_to_specific_language.ipynb b/docs/examples/translation_to_specific_language.ipynb index c8dacdc39..26f3a345d 100644 --- a/docs/examples/translation_to_specific_language.ipynb +++ b/docs/examples/translation_to_specific_language.ipynb @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 1, "metadata": { "tags": [] }, @@ -32,30 +32,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "Collecting alt-profanity-check\n", - " Downloading alt_profanity_check-1.5.0.tar.gz (758 kB)\n", - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m759.0/759.0 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", - "\u001b[?25h Installing build dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", - "\u001b[?25h Installing backend dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25hRequirement already satisfied: scikit-learn==1.5.0 in ./.venv/lib/python3.10/site-packages (from alt-profanity-check) (1.5.0)\n", - "Requirement already satisfied: joblib>=1.4.0 in ./.venv/lib/python3.10/site-packages (from alt-profanity-check) (1.4.2)\n", - "Requirement already satisfied: numpy>=1.19.5 in ./.venv/lib/python3.10/site-packages (from scikit-learn==1.5.0->alt-profanity-check) (1.26.4)\n", - "Requirement already satisfied: scipy>=1.6.0 in ./.venv/lib/python3.10/site-packages (from scikit-learn==1.5.0->alt-profanity-check) (1.13.1)\n", - "Requirement already satisfied: threadpoolctl>=3.1.0 in ./.venv/lib/python3.10/site-packages (from scikit-learn==1.5.0->alt-profanity-check) (3.5.0)\n", - "Building wheels for collected packages: alt-profanity-check\n", - " Building wheel for alt-profanity-check (pyproject.toml) ... \u001b[?25ldone\n", - "\u001b[?25h Created wheel for alt-profanity-check: filename=alt_profanity_check-1.5.0-py3-none-any.whl size=758311 sha256=e0f54f82189ad2c90aeb27cb9239175c71d38606836be9e4762fb64b2e2de0a0\n", - " Stored in directory: /Users/wyatt/Library/Caches/pip/wheels/18/c3/20/637574a9badb43cace85202ca31f49f47e3fe65e076459f3ed\n", - "Successfully built alt-profanity-check\n", - "Installing collected packages: alt-profanity-check\n", - "Successfully installed alt-profanity-check-1.5.0\n" + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.2\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" ] } ], "source": [ - "! pip install alt-profanity-check" + "! pip install alt-profanity-check --quiet" ] }, { @@ -80,30 +64,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/wyatt/Projects/guardrails/docs/examples/.venv/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n", - "/Users/wyatt/Projects/guardrails/guardrails/validators/__init__.py:51: FutureWarning: \n", - " Importing validators from `guardrails.validators` is deprecated.\n", - " All validators are now available in the Guardrails Hub. Please install\n", - " and import them from the hub instead. All validators will be\n", - " removed from this module in the next major release.\n", - "\n", - " Install with: `guardrails hub install hub:///`\n", - " Import as: from guardrails.hub import `ValidatorName`\n", - " \n", - " warn(\n" - ] - } - ], + "outputs": [], "source": [ "from profanity_check import predict\n", "from guardrails.validators import (\n", @@ -139,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": { "tags": [] }, @@ -163,7 +128,7 @@ "\n", "${statement_to_be_translated}\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\n", "\n", "\n", @@ -179,23 +144,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/wyatt/Projects/guardrails/guardrails/validator_base.py:460: FutureWarning: Accessing `IsProfanityFree` using\n", - "`from guardrails.validators import IsProfanityFree` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import ProfanityFree` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/profanity_free.\n", - "\n", - " warn(\n" - ] - } - ], + "outputs": [], "source": [ "from pydantic import BaseModel, Field\n", "\n", @@ -204,7 +155,7 @@ "\n", "${statement_to_be_translated}\n", "\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\"\"\"\n", "\n", "\n", @@ -239,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -257,20 +208,11 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/wyatt/Projects/guardrails/guardrails/prompt/base_prompt.py:59: FutureWarning: Prompt Primitives are moving! To keep the same behaviour, switch from `json` constants to `xml` constants. Example: ${gr.complete_json_suffix} -> ${gr.complete_xml_suffix}\n", - " warn(\n" - ] - } - ], + "outputs": [], "source": [ "guard = gd.Guard.from_rail_string(rail_str)" ] @@ -284,68 +226,100 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "guard = gd.Guard.from_pydantic(output_class=Translation)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, `statement_to_be_translated` is the the statement and will be provided by the user at runtime." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Wrap the LLM API call with `Guard`" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, let's try translating a statement that doesn't have any profanity in it." + ] + }, + { + "cell_type": "code", + "execution_count": 13, "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/wyatt/Projects/guardrails/guardrails/validator_base.py:460: FutureWarning: Accessing `IsProfanityFree` using\n", - "`from guardrails.validators import IsProfanityFree` is deprecated and\n", - "support will be removed after version 0.5.x. Please switch to the Guardrails Hub syntax:\n", - "`from guardrails.hub import ProfanityFree` for future updates and support.\n", - "For additional details, please visit: https://hub.guardrailsai.com/validator/guardrails/profanity_free.\n", - "\n", - " warn(\n", - "/Users/wyatt/Projects/guardrails/guardrails/prompt/base_prompt.py:59: FutureWarning: Prompt Primitives are moving! To keep the same behaviour, switch from `json` constants to `xml` constants. Example: ${gr.complete_json_suffix} -> ${gr.complete_xml_suffix}\n", - " warn(\n" - ] + "data": { + "text/html": [ + "
Validated Output: {'translated_statement': 'chicken quesadilla'}\n",
+       "
\n" + ], + "text/plain": [ + "Validated Output: \u001b[1m{\u001b[0m\u001b[32m'translated_statement'\u001b[0m: \u001b[32m'chicken quesadilla'\u001b[0m\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "guard = gd.Guard.from_pydantic(output_class=Translation, prompt=prompt)" + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "raw_llm_response, validated_response, *rest = guard(\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={\"statement_to_be_translated\": \"quesadilla de pollo\"},\n", + " model=\"gpt-4o\",\n", + " max_tokens=2048,\n", + " temperature=0,\n", + ")\n", + "\n", + "print(f\"Validated Output: {validated_response}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We see the prompt that will be sent to the LLM:" + "We can see the prompt that was sent to the LLM:" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": { "tags": [] }, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/8n/8qwytjb11kj_46_w3n2v4jzw0000gn/T/ipykernel_6330/3983563700.py:1: DeprecationWarning: 'Guard.base_prompt' is deprecated and will be removed in versions 0.5.x and beyond. Use 'Guard.history.last.prompt' instead.\n", - " print(guard.base_prompt)\n" - ] - }, { "data": { "text/html": [ "
\n",
        "Translate the given statement into english language:\n",
        "\n",
-       "${statement_to_be_translated}\n",
+       "quesadilla de pollo\n",
        "\n",
        "\n",
        "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
        "\n",
        "<output>\n",
-       "    <string name=\"translated_statement\" description=\"Translate the given statement into english language\" \n",
-       "format=\"is-profanity-free\"/>\n",
+       "  <string description=\"Translate the given statement into english language\" format=\"is-profanity-free\" \n",
+       "name=\"translated_statement\" required=\"true\"></string>\n",
        "</output>\n",
        "\n",
-       "\n",
        "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n",
        "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n",
        "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n",
@@ -364,17 +338,16 @@
        "\n",
        "Translate the given statement into english language:\n",
        "\n",
-       "$\u001b[1m{\u001b[0mstatement_to_be_translated\u001b[1m}\u001b[0m\n",
+       "quesadilla de pollo\n",
        "\n",
        "\n",
        "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
        "\n",
        "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n",
-       "\u001b[39m    \u001b[0m\n",
+       "\u001b[39m  <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n",
        "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n",
        "\n",
-       "\n",
        "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n",
        "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n",
        "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n",
@@ -394,74 +367,19 @@
     }
    ],
    "source": [
-    "print(guard.base_prompt)"
+    "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Here, `statement_to_be_translated` is the the statement and will be provided by the user at runtime."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Step 3: Wrap the LLM API call with `Guard`"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "First, let's try translating a statement that doesn't have any profanity in it."
+    "We can also take a look at the output of the LLM and the validated output using the Guard's internal logs:"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "
Validated Output: {'translated_statement': 'Chicken quesadilla'}\n",
-       "
\n" - ], - "text/plain": [ - "Validated Output: \u001b[1m{\u001b[0m\u001b[32m'translated_statement'\u001b[0m: \u001b[32m'Chicken quesadilla'\u001b[0m\u001b[1m}\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", - " prompt_params={\"statement_to_be_translated\": \"quesadilla de pollo\"},\n", - " model=\"gpt-3.5-turbo\",\n", - " max_tokens=2048,\n", - " temperature=0,\n", - ")\n", - "\n", - "print(f\"Validated Output: {validated_response}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can take a look at the output of the LLM and the validated output using the Guard's internal logs:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -470,48 +388,52 @@ "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Translate the given statement into english language:                                                    │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ quesadilla de pollo                                                                                     │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <string name=\"translated_statement\" description=\"Translate the given statement into english         │ │\n",
-       "    │ │ language\" format=\"is-profanity-free\"/>                                                                  │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ Translate the given statement into english language:                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ quesadilla de pollo                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <string description=\"Translate the given statement into english language\"                  │ │ │\n",
+       "    │ │ │      │ format=\"is-profanity-free\" name=\"translated_statement\" required=\"true\"></string>             │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ {\"translated_statement\":\"Chicken quesadilla\"}                                                           │ │\n",
+       "    │ │ ```json                                                                                                 │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"translated_statement\": \"chicken quesadilla\"                                                          │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
+       "    │ │ ```                                                                                                     │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ {'translated_statement': 'Chicken quesadilla'}                                                          │ │\n",
+       "    │ │ {'translated_statement': 'chicken quesadilla'}                                                          │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
        "
\n" @@ -520,48 +442,52 @@ "Logs\n", "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTranslate the given statement into english language:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mquesadilla de pollo\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTranslate the given statement into english language: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mquesadilla de pollo \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`. \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior: \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE', \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index': \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}` \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", + " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\"translated_statement\":\"Chicken quesadilla\"}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```json\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \"translated_statement\": \"chicken quesadilla\"\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m```\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'translated_statement': 'Chicken quesadilla'}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'translated_statement': 'chicken quesadilla'}\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" ] @@ -586,7 +512,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": { "tags": [] }, @@ -606,10 +532,13 @@ } ], "source": [ + "# Set your MISTRAL_API_KEY as an environment variable\n", + "# os.environ[\"MISTRAL_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", " prompt_params={\"statement_to_be_translated\": \"убей себя\"},\n", - " model=\"gpt-3.5-turbo\",\n", + " model=\"mistral/mistral-small-latest\",\n", " max_tokens=2048,\n", " temperature=0,\n", ")\n", @@ -627,7 +556,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -636,45 +565,47 @@ "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Translate the given statement into english language:                                                    │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ убей себя                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Given below is XML that describes the information to extract from this document and the tags to extract │ │\n",
-       "    │ │ it into.                                                                                                │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ <output>                                                                                                │ │\n",
-       "    │ │     <string name=\"translated_statement\" description=\"Translate the given statement into english         │ │\n",
-       "    │ │ language\" format=\"is-profanity-free\"/>                                                                  │ │\n",
-       "    │ │ </output>                                                                                               │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the │ │\n",
-       "    │ │ `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding  │ │\n",
-       "    │ │ XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g.        │ │\n",
-       "    │ │ requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere,     │ │\n",
-       "    │ │ enter `null`.                                                                                           │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:                          │ │\n",
-       "    │ │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`                     │ │\n",
-       "    │ │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE', 'STRING TWO',     │ │\n",
-       "    │ │ etc.]}`                                                                                                 │ │\n",
-       "    │ │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer name=\"index\"          │ │\n",
-       "    │ │ format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index': 1}}`                        │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │                                                                                                         │ │\n",
+       "    │ │ No prompt                                                                                               │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely       │ │\n",
-       "    │ │ adhering to the provided XML schemas.                                                                   │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
+       "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
+       "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
+       "    │ │ │ user │                                                                                              │ │ │\n",
+       "    │ │ │      │ Translate the given statement into english language:                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ убей себя                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Given below is XML that describes the information to extract from this document and the tags │ │ │\n",
+       "    │ │ │      │ to extract it into.                                                                          │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ <output>                                                                                     │ │ │\n",
+       "    │ │ │      │   <string description=\"Translate the given statement into english language\"                  │ │ │\n",
+       "    │ │ │      │ format=\"is-profanity-free\" name=\"translated_statement\" required=\"true\"></string>             │ │ │\n",
+       "    │ │ │      │ </output>                                                                                    │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in  │ │ │\n",
+       "    │ │ │      │ JSON is the `name` attribute of the corresponding XML, and the value is of the type          │ │ │\n",
+       "    │ │ │      │ specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including │ │ │\n",
+       "    │ │ │      │ any types and format requests e.g. requests for lists, objects and specific types. Be        │ │ │\n",
+       "    │ │ │      │ correct and concise. If you are unsure anywhere, enter `null`.                               │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │ Here are examples of simple (XML, JSON) pairs that show the expected behavior:               │ │ │\n",
+       "    │ │ │      │ - `<string name='foo' format='two-words lower-case' />` => `{'foo': 'example one'}`          │ │ │\n",
+       "    │ │ │      │ - `<list name='bar'><string format='upper-case' /></list>` => `{\"bar\": ['STRING ONE',        │ │ │\n",
+       "    │ │ │      │ 'STRING TWO', etc.]}`                                                                        │ │ │\n",
+       "    │ │ │      │ - `<object name='baz'><string name=\"foo\" format=\"capitalize two-words\" /><integer            │ │ │\n",
+       "    │ │ │      │ name=\"index\" format=\"1-indexed\" /></object>` => `{'baz': {'foo': 'Some String', 'index':     │ │ │\n",
+       "    │ │ │      │ 1}}`                                                                                         │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ │      │                                                                                              │ │ │\n",
+       "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ {\"translated_statement\":\"Kill yourself\"}                                                                │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"translated_statement\": \"Kill yourself\"                                                               │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
        "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {'translated_statement': ''}                                                                            │ │\n",
@@ -686,45 +617,47 @@
        "Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
        "    │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTranslate the given statement into english language:\u001b[0m\u001b[48;2;240;248;255m                                                   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mубей себя\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mGiven below is XML that describes the information to extract from this document and the tags to extract\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mit into.\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                               \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m    \u001b[0m\u001b[48;2;240;248;255m                                                                 \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m`name` attribute of the corresponding XML, and the value is of the type specified by the corresponding \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mXML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. \u001b[0m\u001b[48;2;240;248;255m      \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mrequests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255menter `null`.\u001b[0m\u001b[48;2;240;248;255m                                                                                          \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mHere are examples of simple (XML, JSON) pairs that show the expected behavior:\u001b[0m\u001b[48;2;240;248;255m                         \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'foo': 'example one'}`\u001b[0m\u001b[48;2;240;248;255m                    \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{\"bar\": ['STRING ONE', 'STRING TWO', \u001b[0m\u001b[48;2;240;248;255m   \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255metc.]}`\u001b[0m\u001b[48;2;240;248;255m                                                                                                \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m- `` => `{'baz': {'foo': 'Some String', 'index': 1}}`\u001b[0m\u001b[48;2;240;248;255m                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
-       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m                                                                                                       \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
+       "    │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m                                                                                              \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n",
        "    │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, able to express yourself purely through JSON, strictly and precisely \u001b[0m\u001b[48;2;255;240;242m     \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242madhering to the provided XML schemas.\u001b[0m\u001b[48;2;255;240;242m                                                                  \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n",
-       "    │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mRole\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[1;48;2;231;223;235mContent                                                                                     \u001b[0m\u001b[1;48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┃\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235muser\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mTranslate the given statement into english language:                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mубей себя                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mGiven below is XML that describes the information to extract from this document and the tags\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mto extract it into.                                                                         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                   \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mONLY return a valid JSON object (no other text is necessary), where the key of the field in \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mJSON is the `name` attribute of the corresponding XML, and the value is of the type         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mspecified by the corresponding XML's tag. The JSON MUST conform to the XML format, including\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235many types and format requests e.g. requests for lists, objects and specific types. Be       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mcorrect and concise. If you are unsure anywhere, enter `null`.                              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mHere are examples of simple (XML, JSON) pairs that show the expected behavior:              \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'foo': 'example one'}`         \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{\"bar\": ['STRING ONE',       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m'STRING TWO', etc.]}`                                                                       \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m- `` => `{'baz': {'foo': 'Some String', 'index':    \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m1}}`                                                                                        \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
-       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\"translated_statement\":\"Kill yourself\"}\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m  \"translated_statement\": \"Kill yourself\"\u001b[0m\u001b[48;2;245;245;220m                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
+       "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m{'translated_statement': ''}\u001b[0m\u001b[48;2;240;255;240m                                                                           \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n",
@@ -757,7 +690,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.3"
+   "version": "3.12.3"
   }
  },
  "nbformat": 4,
diff --git a/docs/examples/translation_with_quality_check.ipynb b/docs/examples/translation_with_quality_check.ipynb
index bc7a69d16..6a24eabd2 100644
--- a/docs/examples/translation_with_quality_check.ipynb
+++ b/docs/examples/translation_with_quality_check.ipynb
@@ -2,42 +2,9 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": null,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/brainlogic/\u001b[0m\u001b[95mhigh_quality_translation...\u001b[0m\n",
-      "\u001b[2K\u001b[32m[==  ]\u001b[0m Fetching manifestst\n",
-      "\u001b[2K\u001b[32m[=   ]\u001b[0m Downloading dependenciespendencies  Running command git clone --filter=blob:none --quiet https://github.com/BrainLogicHub/high_quality_translation_validator.git /private/var/folders/c8/jqt82fpx785dpwpp36ljkgm40000gn/T/pip-req-build-cmoa3yt3\n",
-      "\u001b[2K\u001b[32m[ ===]\u001b[0m Downloading dependencies\u001b[33mWARNING: Target directory /Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/guardrails/hub/brainlogic/high_quality_translation/validator already exists. Specify --upgrade to force replacement.\u001b[0m\u001b[33m\n",
-      "\u001b[0m\u001b[33mWARNING: Target directory /Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/guardrails/hub/brainlogic/high_quality_translation/high_quality_translation-0.0.0.dist-info already exists. Specify --upgrade to force replacement.\u001b[0m\u001b[33m\n",
-      "\u001b[2K\u001b[32m[  ==]\u001b[0m Downloading dependencies\n",
-      "\u001b[2K\u001b[32m[   =]\u001b[0m Running post-install setuptall setup/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:441: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n",
-      "  _torch_pytree._register_pytree_node(\n",
-      "\u001b[2K\u001b[32m[====]\u001b[0m Running post-install setup/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:309: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n",
-      "  _torch_pytree._register_pytree_node(\n",
-      "\u001b[2K\u001b[32m[=== ]\u001b[0m Running post-install setup/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:309: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n",
-      "  _torch_pytree._register_pytree_node(\n",
-      "Fetching 5 files: 100%|████████████████████████| 5/5 [00:00<00:00, 92794.34it/s]\n",
-      "\u001b[2K\u001b[32m[====]\u001b[0m Running post-install setupLightning automatically upgraded your loaded checkpoint from v1.8.2 to v2.2.4. To apply the upgrade to your files permanently, run `python -m pytorch_lightning.utilities.upgrade_checkpoint ../../../../.cache/huggingface/hub/models--Unbabel--wmt22-cometkiwi-da/snapshots/b3a8aea5a5fc22db68a554b92b3d96eb6ea75cc9/checkpoints/model.ckpt`\n",
-      "\u001b[2K\u001b[32m[ ===]\u001b[0m Running post-install setupEncoder model frozen.\n",
-      "\u001b[2K\u001b[32m[    ]\u001b[0m Running post-install setup/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/pytorch_lightning/core/saving.py:188: Found keys that are not in the model state dict but in the checkpoint: ['encoder.model.embeddings.position_ids']\n",
-      "\u001b[2K\u001b[32m[   =]\u001b[0m Running post-install setup\n",
-      "\u001b[1A\u001b[2K✅Successfully installed brainlogic/high_quality_translation!\n",
-      "\n",
-      "\n",
-      "\u001b[1mImport validator:\u001b[0m\n",
-      "from guardrails.hub import HighQualityTranslation\n",
-      "\n",
-      "\u001b[1mGet more info:\u001b[0m\n",
-      "\u001b[4;94mhttps://hub.guardrailsai.com/validator/brainlogic/high_quality_translation\u001b[0m\n",
-      "\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "!guardrails hub install hub://brainlogic/high_quality_translation"
    ]
@@ -70,11 +37,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
-    "import openai\n",
     "from pydantic import BaseModel, Field\n",
     "from guardrails import Guard\n",
     "from rich import print\n",
@@ -95,43 +61,11 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": null,
    "metadata": {
     "tags": []
    },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Loading the model Unbabel/wmt22-cometkiwi-da...\n"
-     ]
-    },
-    {
-     "data": {
-      "application/vnd.jupyter.widget-view+json": {
-       "model_id": "87fd6ea1db6d49a0af904871984c3aa6",
-       "version_major": 2,
-       "version_minor": 0
-      },
-      "text/plain": [
-       "Fetching 5 files:   0%|          | 0/5 [00:00Raw LLM Output: I have no idea what I should write here.\n",
-       "
\n" - ], - "text/plain": [ - "Raw LLM Output: I have no idea what I should write here.\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
Validated Output: I have no idea what I should write here.\n",
-       "
\n" - ], - "text/plain": [ - "Validated Output: I have no idea what I should write here.\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", "statement = \"Ich habe keine Ahnung, was ich hier schreiben soll.\"\n", "\n", "res = guard(\n", - " openai.chat.completions.create,\n", - " prompt=prompt,\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", " prompt_params={\"statement_to_be_translated\": statement},\n", " metadata={\"translation_source\": statement},\n", " model=\"gpt-3.5-turbo\",\n", @@ -244,65 +126,9 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Translate the given statement into English:                                                             │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ │ Ich habe keine Ahnung, was ich hier schreiben soll.                                                     │ │\n",
-       "    │ │                                                                                                         │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭───────────────────────────────────────────── Instructions ──────────────────────────────────────────────╮ │\n",
-       "    │ │ You are a helpful assistant, expressing yourself through a string.                                      │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ I have no idea what I should write here.                                                                │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ 'I have no idea what I should write here.'                                                              │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "
\n" - ], - "text/plain": [ - "Logs\n", - "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", - " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mTranslate the given statement into English:\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mIch habe keine Ahnung, was ich hier schreiben soll.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╭─\u001b[0m\u001b[48;2;255;240;242m────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m Instructions \u001b[0m\u001b[48;2;255;240;242m─────────────────────────────────────────────\u001b[0m\u001b[48;2;255;240;242m─╮\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m│\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242mYou are a helpful assistant, expressing yourself through a string.\u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m \u001b[0m\u001b[48;2;255;240;242m│\u001b[0m │\n", - " │ \u001b[48;2;255;240;242m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mI have no idea what I should write here.\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m'I have no idea what I should write here.'\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "print(guard.history.last.tree)" ] @@ -319,63 +145,9 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "GPU available: True (mps), used: False\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/pytorch_lightning/trainer/setup.py:187: GPU available but not used. You can set it by doing `Trainer(accelerator='gpu')`.\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/pytorch_lightning/trainer/connectors/data_connector.py:436: Consider setting `persistent_workers=True` in 'predict_dataloader' to speed up the dataloader worker initialization.\n", - "\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:441: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n", - " _torch_pytree._register_pytree_node(\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:309: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n", - " _torch_pytree._register_pytree_node(\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:309: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n", - " _torch_pytree._register_pytree_node(\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:441: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n", - " _torch_pytree._register_pytree_node(\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:309: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n", - " _torch_pytree._register_pytree_node(\n", - "/Users/zaydsimjee/workspace/guardrails/.venv/lib/python3.10/site-packages/transformers/utils/generic.py:309: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n", - " _torch_pytree._register_pytree_node(\n", - "Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 8.27it/s]\n" - ] - }, - { - "data": { - "text/html": [ - "
Raw LLM Output: It's such a beautiful day, I'm going to the beach.\n",
-       "
\n" - ], - "text/plain": [ - "Raw LLM Output: It's such a beautiful day, I'm going to the beach.\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
Validated Output: \n",
-       "
\n" - ], - "text/plain": [ - "Validated Output: \n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Parse the code snippet\n", "statement = \"अरे भाऊ, आज रात्री जोरदार पार्टी मारूया, जमून टाकूया आणि धमाल करूया!\"\n", @@ -395,51 +167,9 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
Logs\n",
-       "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
-       "    │ │ No prompt                                                                                               │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
-       "    │ │ No message history.                                                                                     │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
-       "    │ │ It's such a beautiful day, I'm going to the beach.                                                      │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
-       "    │ │ ''                                                                                                      │ │\n",
-       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n",
-       "
\n" - ], - "text/plain": [ - "Logs\n", - "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n", - " │ \u001b[48;2;240;248;255m╭─\u001b[0m\u001b[48;2;240;248;255m───────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m Prompt \u001b[0m\u001b[48;2;240;248;255m────────────────────────────────────────────────\u001b[0m\u001b[48;2;240;248;255m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255mNo prompt\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", - " │ \u001b[48;2;240;248;255m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Message History \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235mNo message history.\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n", - " │ \u001b[48;2;231;223;235m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╭─\u001b[0m\u001b[48;2;245;245;220m───────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m Raw LLM Output \u001b[0m\u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mIt's such a beautiful day, I'm going to the beach.\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", - " │ \u001b[48;2;245;245;220m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╭─\u001b[0m\u001b[48;2;240;255;240m──────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m Validated Output \u001b[0m\u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m''\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", - " │ \u001b[48;2;240;255;240m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m │\n", - " ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "print(guard.history.last.tree)" ] @@ -470,7 +200,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.0" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/docs/examples/valid_chess_moves.ipynb b/docs/examples/valid_chess_moves.ipynb index 57980d31d..40a7880b5 100644 --- a/docs/examples/valid_chess_moves.ipynb +++ b/docs/examples/valid_chess_moves.ipynb @@ -22,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -32,19 +32,21 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: chess in /home/zayd/workspace/shreya/guardrails/.venv/lib/python3.11/site-packages (1.10.0)\n" + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.1.2\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" ] } ], "source": [ - "! pip install chess" + "! pip install chess --quiet" ] }, { @@ -66,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -106,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -121,7 +123,7 @@ "\n", "Generate a move for the chess board. The board is currently in the following state:\n", "${board_state}\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\n", "\n", "\n", @@ -137,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -146,7 +148,7 @@ "prompt = \"\"\"\n", "Generate a move for the chess board. The board is currently in the following state:\n", "${board_state}\n", - "${gr.complete_json_suffix}\n", + "${gr.complete_xml_suffix}\n", "\"\"\"\n", "\n", "class ChessMove(BaseModel):\n", @@ -178,7 +180,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -194,11 +196,11 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ - "guard = gd.Guard.from_pydantic(output_class=ChessMove, prompt=prompt)" + "guard = gd.Guard.from_pydantic(output_class=ChessMove)" ] }, { @@ -206,12 +208,81 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We see the prompt that will be sent to the LLM. The `{board_state}` is substituted with the current state of the board." + "Let's get the reference to the board." ] }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "
r n b q k b n r\n",
+       "p p p p p p p p\n",
+       ". . . . . . . .\n",
+       ". . . . . . . .\n",
+       ". . . . . . . .\n",
+       ". . . . . . . .\n",
+       "P P P P P P P P\n",
+       "R N B Q K B N R
" + ], + "text/plain": [ + "Board('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "board = guard._validator_map.get(\"$.move\")[0].board\n", + "board" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Step 3: Wrap the LLM API call with `Guard`" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", + "\n", + "raw_llm_response, validated_response, *rest = guard(\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", + " prompt_params={\n", + " \"board_state\": str(board.move_stack)\n", + " if board.move_stack\n", + " else \"Starting position.\"\n", + " },\n", + " model=\"gpt-3.5-turbo\",\n", + " max_tokens=2048,\n", + " temperature=0.3,\n", + ")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see in the prompt that was sent to the LLM, the `{board_state}` parameter is substituted with the current state of the board." + ] + }, + { + "cell_type": "code", + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -219,15 +290,15 @@ "text/html": [ "
\n",
        "Generate a move for the chess board. The board is currently in the following state:\n",
-       "${board_state}\n",
+       "Starting position.\n",
        "\n",
        "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
        "\n",
        "<output>\n",
-       "    <string name=\"move\" format=\"is-valid-chess-move\" description=\"A move in standard algebraic notation.\"/>\n",
+       "  <string description=\"A move in standard algebraic notation.\" format=\"is-valid-chess-move\" name=\"move\" \n",
+       "required=\"true\"></string>\n",
        "</output>\n",
        "\n",
-       "\n",
        "ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` \n",
        "attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\n",
        "MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \n",
@@ -245,15 +316,15 @@
       "text/plain": [
        "\n",
        "Generate a move for the chess board. The board is currently in the following state:\n",
-       "$\u001b[1m{\u001b[0mboard_state\u001b[1m}\u001b[0m\n",
+       "Starting position.\n",
        "\n",
        "Given below is XML that describes the information to extract from this document and the tags to extract it into.\n",
        "\n",
        "\u001b[1m<\u001b[0m\u001b[1;95moutput\u001b[0m\u001b[39m>\u001b[0m\n",
-       "\u001b[39m    \u001b[0m\n",
+       "\u001b[39m  <\u001b[0m\u001b[35m/\u001b[0m\u001b[95mstring\u001b[0m\u001b[39m>\u001b[0m\n",
        "\u001b[39m<\u001b[0m\u001b[35m/\u001b[0m\u001b[95moutput\u001b[0m\u001b[39m>\u001b[0m\n",
        "\n",
-       "\n",
        "\u001b[39mONLY return a valid JSON object \u001b[0m\u001b[1;39m(\u001b[0m\u001b[39mno other text is necessary\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m, where the key of the field in JSON is the `name` \u001b[0m\n",
        "\u001b[39mattribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON\u001b[0m\n",
        "\u001b[39mMUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and \u001b[0m\n",
@@ -273,82 +344,7 @@
     }
    ],
    "source": [
-    "print(guard.base_prompt)"
-   ]
-  },
-  {
-   "attachments": {},
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "Let's get the reference to the board."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 73,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "image/svg+xml": [
-       "
r n b q k b n r\n",
-       "p p p p p p p p\n",
-       ". . . . . . . .\n",
-       ". . . . . . . .\n",
-       ". . . . . . . .\n",
-       ". . . . . . . .\n",
-       "P P P P P P P P\n",
-       "R N B Q K B N R
" - ], - "text/plain": [ - "Board('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "board = guard.output_schema.root_datatype.children.__getattribute__(\"move\").validators[0].board\n", - "board" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Wrap the LLM API call with `Guard`" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Async event loop found, but guard was invoked synchronously.For validator parallelization, please call `validate_async` instead.\n" - ] - } - ], - "source": [ - "import openai\n", - "\n", - "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", - " prompt_params={\n", - " \"board_state\": str(board.move_stack)\n", - " if board.move_stack\n", - " else \"Starting position.\"\n", - " },\n", - " model=\"gpt-3.5-turbo\",\n", - " max_tokens=2048,\n", - " temperature=0.3,\n", - ")" + "print(guard.history.last.iterations.last.inputs.msg_history[0][\"content\"])" ] }, { @@ -362,7 +358,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -385,7 +381,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -404,7 +400,7 @@ "Board('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1')" ] }, - "execution_count": 76, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -423,7 +419,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -442,7 +438,7 @@ "Board('rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2')" ] }, - "execution_count": 77, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -462,21 +458,12 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 30, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Async event loop found, but guard was invoked synchronously.For validator parallelization, please call `validate_async` instead.\n", - "Async event loop found, but guard was invoked synchronously.For validator parallelization, please call `validate_async` instead.\n" - ] - } - ], + "outputs": [], "source": [ "raw_llm_response, validated_response, *rest = guard(\n", - " openai.chat.completions.create,\n", + " messages=[{\"role\":\"user\", \"content\": prompt}],\n", " prompt_params={\n", " \"board_state\": str(board.move_stack)\n", " if board.move_stack\n", @@ -490,7 +477,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -501,15 +488,15 @@ ". . . . . . . .\n", ". . . . p . . .\n", ". . . . P . . .\n", - ". . . . . . . .\n", + ". . . . . N . .\n", "P P P P . P P P\n", - "R N B Q K B N R
" + "R N B Q K B . R
" ], "text/plain": [ - "Board('rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2')" + "Board('rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2')" ] }, - "execution_count": 79, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -520,21 +507,28 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 32, "metadata": {}, "outputs": [ { - "ename": "IllegalMoveError", - "evalue": "illegal san: 'Nc6' in rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mIllegalMoveError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[80], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m board\u001b[39m.\u001b[39;49mpush_san(\u001b[39m\"\u001b[39;49m\u001b[39mNc6\u001b[39;49m\u001b[39m\"\u001b[39;49m)\n\u001b[1;32m 2\u001b[0m board\n", - "File \u001b[0;32m~/workspace/shreya/guardrails/.venv/lib/python3.11/site-packages/chess/__init__.py:3105\u001b[0m, in \u001b[0;36mBoard.push_san\u001b[0;34m(self, san)\u001b[0m\n\u001b[1;32m 3091\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mpush_san\u001b[39m(\u001b[39mself\u001b[39m, san: \u001b[39mstr\u001b[39m) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Move:\n\u001b[1;32m 3092\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 3093\u001b[0m \u001b[39m Parses a move in standard algebraic notation, makes the move and puts\u001b[39;00m\n\u001b[1;32m 3094\u001b[0m \u001b[39m it onto the move stack.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 3103\u001b[0m \u001b[39m - :exc:`AmbiguousMoveError` if the SAN is ambiguous.\u001b[39;00m\n\u001b[1;32m 3104\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 3105\u001b[0m move \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mparse_san(san)\n\u001b[1;32m 3106\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mpush(move)\n\u001b[1;32m 3107\u001b[0m \u001b[39mreturn\u001b[39;00m move\n", - "File \u001b[0;32m~/workspace/shreya/guardrails/.venv/lib/python3.11/site-packages/chess/__init__.py:3087\u001b[0m, in \u001b[0;36mBoard.parse_san\u001b[0;34m(self, san)\u001b[0m\n\u001b[1;32m 3084\u001b[0m matched_move \u001b[39m=\u001b[39m move\n\u001b[1;32m 3086\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m matched_move:\n\u001b[0;32m-> 3087\u001b[0m \u001b[39mraise\u001b[39;00m IllegalMoveError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39millegal san: \u001b[39m\u001b[39m{\u001b[39;00msan\u001b[39m!r}\u001b[39;00m\u001b[39m in \u001b[39m\u001b[39m{\u001b[39;00m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mfen()\u001b[39m}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[1;32m 3089\u001b[0m \u001b[39mreturn\u001b[39;00m matched_move\n", - "\u001b[0;31mIllegalMoveError\u001b[0m: illegal san: 'Nc6' in rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2" - ] + "data": { + "image/svg+xml": [ + "
r . b q k b n r\n",
+       "p p p p . p p p\n",
+       ". . n . . . . .\n",
+       ". . . . p . . .\n",
+       ". . . . P . . .\n",
+       ". . . . . N . .\n",
+       "P P P P . P P P\n",
+       "R N B Q K B . R
" + ], + "text/plain": [ + "Board('r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3')" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -559,7 +553,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.6" + "version": "3.12.3" }, "orig_nbformat": 4, "vscode": { diff --git a/docs/examples/value_within_distribution.ipynb b/docs/examples/value_within_distribution.ipynb index 15192ed00..8f3730e7c 100644 --- a/docs/examples/value_within_distribution.ipynb +++ b/docs/examples/value_within_distribution.ipynb @@ -10,26 +10,16 @@ "output_type": "stream", "text": [ "Installing hub:\u001b[35m/\u001b[0m\u001b[35m/guardrails/\u001b[0m\u001b[95msimilar_to_previous_values...\u001b[0m\n", - "\u001b[2K\u001b[32m[= ]\u001b[0m Fetching manifestst\n", - "\u001b[2K\u001b[32m[== ]\u001b[0m Downloading dependencies Running command git clone --filter=blob:none --quiet https://github.com/guardrails-ai/similar_to_previous_values.git /private/var/folders/w2/ssf16z690zd7_4dggw0y5s_m0000gn/T/pip-req-build-8nvu7jlq\n", - "\u001b[2K\u001b[32m[ ===]\u001b[0m Downloading dependencies\n", - "\u001b[2K\u001b[32m[ ===]\u001b[0m Running post-install setuptall setup/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.11/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", " warnings.warn(\n", - "\u001b[2K\u001b[32m[ ==]\u001b[0m Running post-install setup\n", - "\u001b[1A\u001b[2K✅Successfully installed guardrails/similar_to_previous_values!\n", + "✅Successfully installed guardrails/similar_to_previous_values!\n", "\n", - "\n", - "\u001b[1mImport validator:\u001b[0m\n", - "from guardrails.hub import SimilarToPreviousValues\n", - "\n", - "\u001b[1mGet more info:\u001b[0m\n", - "\u001b[4;94mhttps://hub.guardrailsai.com/validator/guardrails/similar_to_previous_values\u001b[0m\n", "\n" ] } ], "source": [ - "!guardrails hub install hub://guardrails/similar_to_previous_values" + "!guardrails hub install hub://guardrails/similar_to_previous_values --quiet" ] }, { @@ -49,9 +39,18 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/examples/.venv/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from tqdm.autonotebook import tqdm, trange\n" + ] + } + ], "source": [ "# Create the Guard with the SimilarToList validator\n", "from typing import Union\n", @@ -75,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -105,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -142,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -167,19 +166,9 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 7, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -204,19 +193,9 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 8, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n", - "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -256,7 +235,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.12.1" }, "orig_nbformat": 4 }, diff --git a/docs/faq.md b/docs/faq.md index fe1e41082..5d92c9a44 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,5 +1,76 @@ # Frequently Asked Questions +## I'm seeing a PromptCallableException when invoking my Guard. What should I do? + +If you see an exception that looks like this + +``` +PromptCallableException: The callable `fn` passed to `Guard(fn, ...)` failed with the following error: `custom_llm_func() got an unexpected keyword argument 'messages'`. Make sure that `fn` can be called as a function that takes in a single prompt string and returns a string. +``` + +It means that the call to the LLM failed. This is usually triggered for one of the following reasons: + +1. An API key is not present or not passed correctly to the LLM +1. The LLM API was passed arguments it doesn't expect. Our recommendation is to use the LiteLLM standard, and pass arguments that conform to that standard directly in the guard callable. It's helpful as a debugging step to remove all other arguments or to try and use the same arguments in a LiteLLM client directly. +1. The LLM API is down or experiencing issues. This is usually temporary, and you can use LiteLLM or the LLM client directly to verify if the API is working as expected. +1. You passed a custom LLM callable, and it either doesn't conform to the expected signature or it throws an error during execution. Make sure that the custom LLM callable can be called as a function that takes in a single prompt string and returns a string. + +## How can I host Guardrails as its own server + +Guardrails can run totally on the server as of version 0.5.0. You can use the `guardrails-ai` package to run Guardrails as a server. You can find more information on how to do this in the [Guardrails AI documentation](https://docs.guardrails.ai/guardrails_ai/installation). + +## Which validators should I use? Where can I find them? + +You can find a variety of validators on the [Guardrails Hub](https://hub.guardrailsai.com). We recommend starting by drilling down into your usecase on the left nav of that page (chatbot, customer support, etc...). We're also coming out with starter packs soon that are generally applicable to common usecases. + +## How does Guardrails impact my LLM app's latency + +tl;dr - guardrails aims to add < 100ms to each LLM request, use our recommendations to speed stuff up. + +We've done a lot of work to make Guardrails perform well. Validating LLMs is not trivial, and because of the different approaches used to solve each kind of validation, performance can vary. Performance can be split into two categories: Guard execution and Validation execution. Guard execution is the time it takes to amend prompts, parse LLM output, delegate validation, and compile validation results. + +Guard execution time is minimal, and should run on the order of microseconds. + +Validation execution time is usually on the order of tens of milliseconds. There are definitely standouts here. For example, some ML-based validators like [RestrictToTopic](https://hub.guardrailsai.com/validator/tryolabs/restricttotopic) can take seconds to run when the model is cold and running locally on a CPU. However, we've seen it run in sub-100ms time when the model is running on GPUs. + +Here are our recommendations: + +1. use streaming when presenting user-facing applications. Streaming allows us to validate smaller chunks (sentences, phrases, etc, depending on the validator), and this can be done in parallel as the LLM generates the rest of the output +1. Host your validator models on GPUs. Guardrails provides inference endpoints for some popular validators, and we're working on making this more accessible. +1. Run Guardrails on its own dedicated server. This allows the library to take advantage of a full set of compute resources to thread out over. It also allows you to scale Guardrails independently of your application +1. In production and performance-testing environments, use telemetry to keep track of validator latency and how it changes over time. This will help you understand right-sizing your infrastructure and identifying bottlenecks in guard execution. + +## How do I setup my own `fix` function for validators in a guard? + +If we have a validator that looks like this +```python +from guardrails.validators import PassResult, FailResult, register_validator + +@register_validator(name="is_cake", data_type="string") +def is_cake(value, metadata): + if value == "cake": + return PassResult() + return FailResult(error_message="This is not a cake.") +``` + +You can override the `fix` behavior by passing it as a function to the Guard object when the validator is declared. + +```python +from guardrails import Guard + +def fix_is_cake(value, metadata): + return "IT IS cake" + +guard = Guard().use(is_cake, on_fail=fix_is_cake) + +res = guard.parse( + llm_output="not cake" +) + +print(res.validated_output) # Validated outputs +# Prints "IT IS cake" +``` + ## I'm encountering an XMLSyntaxError when creating a `Guard` object from a `RAIL` specification. What should I do? Make sure that you are escaping the `&` character in your `RAIL` specification. The `&` character has a special meaning in XML, and so you need to escape it with `&`. For example, if you have a prompt like this: @@ -18,4 +89,23 @@ You need to escape the `&` character like this: ``` +## Are validators all model-based? Are they proprietary to Guardrails? + +Some validators are model based, some validators use LLMs, and some validators are purely logic. They are usually not proprietary, you can see a variety of them on the [Guardrails Hub](https://hub.guardrailsai.com) where they are largely open source and licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). + +This doesn't preclude the creation and use of custom private validators with any given technology, but we are huge believers in the power of open source software. + +## Issues loging in with `guardrails configure` + +If you encounter issues logging in using an API key with `guardrails configure`, they may be caused by one of the following: + +1. Your API key has been revoked, expired, or is invalid. You can check your existing tokens and create a new one at [https://hub.guardrailsai.com/tokens](https://hub.guardrailsai.com/tokens) if necessary. +2. If you're using Windows Powershell, ensure that you paste the token by right-clicking instead of using the keyboard shortcut `CTRL+V`, as the shortcut may cause caret characters to be pasted instead of the clipboard contents. + +If your login issues persist, please check the contents of the ~/.guardrailsrc file to ensure the correct token has been persisted. + +## Where do I get more help if I need it? + If you're still encountering issues, please [open an issue](https://github.com/guardrails-ai/guardrails/issues/new) and we'll help you out! + +We're also available on [Discord](https://discord.gg/U9RKkZSBgx) if you want to chat with us directly. diff --git a/docs/getting_started/ai_validation.md b/docs/getting_started/ai_validation.md new file mode 100644 index 000000000..c11c51bb0 --- /dev/null +++ b/docs/getting_started/ai_validation.md @@ -0,0 +1 @@ +# AI Validation \ No newline at end of file diff --git a/docs/getting_started/contributing.md b/docs/getting_started/contributing.md new file mode 100644 index 000000000..755e562c9 --- /dev/null +++ b/docs/getting_started/contributing.md @@ -0,0 +1,54 @@ +# Contributing + +Welcome and thank you for your interest in contributing to Guardrails! We appreciate all contributions, big or small, from bug fixes to new features. Before diving in, let's go through some guidelines to make the process smoother for everyone. + +## Getting Started + +1. If you're fixing a bug or typo, feel free to submit a Pull Request directly. +2. For new features or bug fix discussions, open an issue or join our [Discord server](https://discord.gg/Jsey3mX98B) to chat with the community. + +## Setting Up Your Environment + +1. Clone the repository: `git clone https://github.com/guardrails-ai/guardrails.git` +2. Enter the project directory: `cd guardrails` +3. Install the project in developer mode (use a virtual environment if preferred): `make dev` +4. Install [pre-commit](https://pre-commit.com/): `pre-commit install` + +## Development Workflow + +Follow these steps before committing your changes: + +1. Ensure tests pass: `make test` +2. Format your code: `make autoformat` +3. Run static analysis: `make type` +4. Update documentation if needed. Docs are located in the `docs` directory. You can serve docs using `mkdocs serve`. + +### Optional: Pre-Commit Hooks + +For convenience, consider [installing the pre-commit hooks](https://pre-commit.com/#installation) provided in the repository. These hooks automatically run tests and formatting checks each time you commit, reducing development overhead. + +## Submitting a Pull Request + +1. Ensure all tests pass and code is formatted. +2. Create a pull request with a clear description of your changes. Link to relevant issues or discussions. Follow [this guide](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) if needed. +3. Address any failing checks before requesting a review. +4. Engage in the code review process and make any necessary changes. +5. Celebrate when your pull request is merged! Your changes will be available in the next Guardrails release. + +Thank you for your contribution and happy coding! + +## Documentation + +Docs are served via docusaurus. To serve docs locally, run the following + +```bash +# install dependencies +pip install -e ".[dev]" + +# install npm dependencies +npm i + +# serve the docs +npm run start +``` +then navigate to `localhost:3000` in your browser. \ No newline at end of file diff --git a/docs/getting_started/guardrails_server.md b/docs/getting_started/guardrails_server.md new file mode 100644 index 000000000..70f99077a --- /dev/null +++ b/docs/getting_started/guardrails_server.md @@ -0,0 +1,117 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Guardrails Server + +## Overview + +In Guardrails v0.5.0, we released the Guardrails Server. The Guardrails server unlocks several usecases and programming languages through features like **OpenAI SDK compatible enpdoints**, remote validator executions, and server-side support of custom functions. + +Together, these features make it easier to get started, and make it possible to host Guardrails in your production infrastructure. + +This document will overview a few of the key features of the Guardrails Server, and how to get started. + +## Walkthrough + +### 1. Install the Guardrails Server +This is done by simply installing the `guardrails-ai` package. See the [installation guide](./quickstart.md) for more information. + +```bash +pip install guardrails-ai; +guardrails configure; +``` + +### 2. Create a Guardrails config file +The Guardrails config file is a python file that includes the Guardrails that you want to use, defined in a `Guard` object. + +We'll use the `create` command on the guardrails CLI to do this. We'll specify the [GibberishText validator](https://hub.guardrailsai.com/validator/guardrails/gibberish_text) from the Guardrails Hub. + + +```bash +guardrails create --validators hub://guardrails/gibberish_text +``` + +:::note +This creates a file called config.py with a Guard object that uses the GibberishText validator. The Guard object still needs to be named. +::: + +Update the guard with a Guard name. Also, have the GibberishText validator throw an exception when it is violated. + +```python +from guardrails import Guard +from guardrails.hub import GibberishText +guard = Guard(name='gibberish_guard') +guard.use(GibberishText(on_fail='exception')) +``` + +### 3. Start the Guardrails Server +The guardrails CLI starts the server on `localhost:8000` by default. An API reference can be found at `https://localhost:8000/docs`. Since guards run on the backend, you also want to set LLM API Keys in the environment. + +```bash +export OPENAI_API_KEY=your_openai_api_key +guardrails start --config config.py +``` + +Guardrails is now running on localhost:8000. + +### 4. Update client to use the Guardrails Server +You need only route your openai (or openai compatible sdk) base_url to the `http://localhost:8000/guards/[guard_name]/openai/v1/` endpoint. Your client code will now throw an exception if the GibberishText validator is violated. Note, this works in multiple languages. + + + + + +```python +import openai +openai.base_url = ( + "http://localhost:8000/guards/gibberish_guard/openai/v1/" +) + +response = openai.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": "Make up some gibberish for me please!" + }] +) + +print(response.choices[0].message.content) +print(response.guardrails['validation_passed']) +``` + + + + +```javascript +const { OpenAI } = require("openai"); + +const openai = new OpenAI({baseURL: "http://127.0.0.1:8000/guards/gibberish_guard/openai/v1/"}); + +async function main() { + const completion = await openai.chat.completions.create({ + messages: [{ role: "system", content: "tell me some gibberish." }], + model: "gpt-3.5-turbo", + }); + + console.log(completion.choices[0]); + console.log(completion.guardrails); +} + +main(); +``` + + + + + + +:::note +A `guardrails` key is added to the response object, which includes the validation results. +::: + +## Learn More +- [Guardrails Server Concepts](../concepts/deploying) +- [Guardrails CLI Reference](../cli) +- [Remote Validation Inference](../concepts/remote_validation_inference) +- [Guardrails Hub](https://hub.guardrailsai.com) + diff --git a/docs/getting_started/help.md b/docs/getting_started/help.md new file mode 100644 index 000000000..75dd79df7 --- /dev/null +++ b/docs/getting_started/help.md @@ -0,0 +1,4 @@ +# Getting help +If you're having trouble using guardrails, please see the FAQ for common + +Please reach out to us on [Discord](https://discord.gg/gw4cR9QvYE) or [Twitter](https://twitter.com/guardrails_ai) if you're still having issues, or just to say "Hi" and see what's up! \ No newline at end of file diff --git a/docs/getting_started/ml_based.md b/docs/getting_started/ml_based.md new file mode 100644 index 000000000..acaf8fb94 --- /dev/null +++ b/docs/getting_started/ml_based.md @@ -0,0 +1,2 @@ +# Machine Learning-based Validation + diff --git a/docs/getting_started/quickstart.md b/docs/getting_started/quickstart.md new file mode 100644 index 000000000..faba54cd1 --- /dev/null +++ b/docs/getting_started/quickstart.md @@ -0,0 +1,187 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Quickstart + +## Introduction + +Guardrails is a framework that validates and structures data from language models. These validations range simple checks like regex matching to more complex checks like competitor analysis. Guardrails can be used with any language model. + +## Installation + +### Download Guardrails (required) +First, install Guardrails for your desired language: + +```bash +pip install guardrails-ai +``` + +### Configure the Guardrails CLI (required) + +```bash +guardrails configure +``` + +## Usage + +1. Install a guardrail from [Guardrails Hub](https://hub.guardrailsai.com). + + ```bash + guardrails hub install hub://guardrails/regex_match --quiet + ``` +2. Create a Guard from the installed guardrail. + + ```python + # Import Guard and Validator + from guardrails.hub import RegexMatch + from guardrails import Guard + + # Initialize the Guard with + guard = Guard().use( + RegexMatch(regex="^[A-Z][a-z]*$") + ) + + print(guard.parse("Caesar").validation_passed) # Guardrail Passes + print( + guard.parse("Caesar Salad") + .validation_passed + ) # Guardrail Fails + ``` +3. Run multiple guardrails within a Guard. + First, install the necessary guardrails from Guardrails Hub. + + ```bash + guardrails hub install hub://guardrails/competitor_check --quiet + guardrails hub install hub://guardrails/toxic_language --quiet + ``` + + Then, create a Guard from the installed guardrails. + + ```python + from guardrails.hub import RegexMatch, ValidLength + from guardrails import Guard + + guard = Guard().use_many( + RegexMatch(regex="^[A-Z][a-z]*$"), + ValidLength(min=1, max=12) + ) + + print(guard.parse("Caesar").validation_passed) # Guardrail Passes + print( + guard.parse("Caesar Salad") + .validation_passed + ) # Guardrail Fails due to regex match + print( + guard.parse("Caesarisagreatleader") + .validation_passed + ) # Guardrail Fails due to length + ``` + +## Structured Data Generation and Validation + +Now, let's go through an example where we ask an LLM to generate fake pet names. + +1. Create a Pydantic [BaseModel](https://docs.pydantic.dev/latest/api/base_model/) that represents the structure of the output we want. + +```py +from pydantic import BaseModel, Field + +class Pet(BaseModel): + pet_type: str = Field(description="Species of pet") + name: str = Field(description="a unique pet name") +``` + +2. create a Guard from the `Pet` class. The Guard can be used to call the LLM in a manner so that the output is formatted to the `Pet` class. Under the hood, this is done by either of two methods: + +(1) Function calling: For LLMs that support function calling, we generate structured data using the function call syntax. + +(2) Prompt optimization: For LLMs that don't support function calling, we add the schema of the expected output to the prompt so that the LLM can generate structured data. + +```py +from guardrails import Guard + +prompt = """ + What kind of pet should I get and what should I name it? + + ${gr.complete_json_suffix_v2} +""" +guard = Guard.from_pydantic(output_class=Pet) + +res = guard( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": prompt + }] +) + +print(f"{res.validated_output}") +``` + +This prints: +``` +{ + "pet_type": "dog", + "name": "Buddy +} +``` + +## Advanced installation instructions + +### Install the Javascript library + +**Note**: The Javascript library works via an I/O bridge to run the underlying Python library. You must have Python 3.16 or greater installed on your system to use the Javascript library. + + +```bash +npm i @guardrails-ai/core +``` + +### Install specific version + + + + + +To install a specific version in Python, run: + +```bash +# pip install guardrails-ai==[version-number] + +# Example: +pip install guardrails-ai==0.5.0a13 +``` + + + + +To install a pre-release version with Javascript, install it with the intended semantic version. + + + + + +### Install from GitHub + +Installing directly from GitHub is useful when a release has not yet been cut with the changes pushed to a branch that you need. Non-released versions may include breaking changes, and may not yet have full test coverage. We recommend using a released version whenever possible. + + + + + +```bash +# pip install git+https://github.com/guardrails-ai/guardrails.git@[branch/commit/tag] +# Example: +pip install git+https://github.com/guardrails-ai/guardrails.git@main +``` + + + + +```bash +npm i git+https://github.com/guardrails-ai/guardrails-js.git +``` + + + + \ No newline at end of file diff --git a/docs/getting_started/structured_data.md b/docs/getting_started/structured_data.md new file mode 100644 index 000000000..998d1f4a6 --- /dev/null +++ b/docs/getting_started/structured_data.md @@ -0,0 +1 @@ +# Structured Data Validation \ No newline at end of file diff --git a/docs/getting_started/why_use.md b/docs/getting_started/why_use.md new file mode 100644 index 000000000..7910cbb3b --- /dev/null +++ b/docs/getting_started/why_use.md @@ -0,0 +1,3 @@ +# Why use Guardrails? + +Lorem ipsum \ No newline at end of file diff --git a/docs/guardrails_ai/faq.md b/docs/guardrails_ai/faq.md index fe1e41082..5d92c9a44 100644 --- a/docs/guardrails_ai/faq.md +++ b/docs/guardrails_ai/faq.md @@ -1,5 +1,76 @@ # Frequently Asked Questions +## I'm seeing a PromptCallableException when invoking my Guard. What should I do? + +If you see an exception that looks like this + +``` +PromptCallableException: The callable `fn` passed to `Guard(fn, ...)` failed with the following error: `custom_llm_func() got an unexpected keyword argument 'messages'`. Make sure that `fn` can be called as a function that takes in a single prompt string and returns a string. +``` + +It means that the call to the LLM failed. This is usually triggered for one of the following reasons: + +1. An API key is not present or not passed correctly to the LLM +1. The LLM API was passed arguments it doesn't expect. Our recommendation is to use the LiteLLM standard, and pass arguments that conform to that standard directly in the guard callable. It's helpful as a debugging step to remove all other arguments or to try and use the same arguments in a LiteLLM client directly. +1. The LLM API is down or experiencing issues. This is usually temporary, and you can use LiteLLM or the LLM client directly to verify if the API is working as expected. +1. You passed a custom LLM callable, and it either doesn't conform to the expected signature or it throws an error during execution. Make sure that the custom LLM callable can be called as a function that takes in a single prompt string and returns a string. + +## How can I host Guardrails as its own server + +Guardrails can run totally on the server as of version 0.5.0. You can use the `guardrails-ai` package to run Guardrails as a server. You can find more information on how to do this in the [Guardrails AI documentation](https://docs.guardrails.ai/guardrails_ai/installation). + +## Which validators should I use? Where can I find them? + +You can find a variety of validators on the [Guardrails Hub](https://hub.guardrailsai.com). We recommend starting by drilling down into your usecase on the left nav of that page (chatbot, customer support, etc...). We're also coming out with starter packs soon that are generally applicable to common usecases. + +## How does Guardrails impact my LLM app's latency + +tl;dr - guardrails aims to add < 100ms to each LLM request, use our recommendations to speed stuff up. + +We've done a lot of work to make Guardrails perform well. Validating LLMs is not trivial, and because of the different approaches used to solve each kind of validation, performance can vary. Performance can be split into two categories: Guard execution and Validation execution. Guard execution is the time it takes to amend prompts, parse LLM output, delegate validation, and compile validation results. + +Guard execution time is minimal, and should run on the order of microseconds. + +Validation execution time is usually on the order of tens of milliseconds. There are definitely standouts here. For example, some ML-based validators like [RestrictToTopic](https://hub.guardrailsai.com/validator/tryolabs/restricttotopic) can take seconds to run when the model is cold and running locally on a CPU. However, we've seen it run in sub-100ms time when the model is running on GPUs. + +Here are our recommendations: + +1. use streaming when presenting user-facing applications. Streaming allows us to validate smaller chunks (sentences, phrases, etc, depending on the validator), and this can be done in parallel as the LLM generates the rest of the output +1. Host your validator models on GPUs. Guardrails provides inference endpoints for some popular validators, and we're working on making this more accessible. +1. Run Guardrails on its own dedicated server. This allows the library to take advantage of a full set of compute resources to thread out over. It also allows you to scale Guardrails independently of your application +1. In production and performance-testing environments, use telemetry to keep track of validator latency and how it changes over time. This will help you understand right-sizing your infrastructure and identifying bottlenecks in guard execution. + +## How do I setup my own `fix` function for validators in a guard? + +If we have a validator that looks like this +```python +from guardrails.validators import PassResult, FailResult, register_validator + +@register_validator(name="is_cake", data_type="string") +def is_cake(value, metadata): + if value == "cake": + return PassResult() + return FailResult(error_message="This is not a cake.") +``` + +You can override the `fix` behavior by passing it as a function to the Guard object when the validator is declared. + +```python +from guardrails import Guard + +def fix_is_cake(value, metadata): + return "IT IS cake" + +guard = Guard().use(is_cake, on_fail=fix_is_cake) + +res = guard.parse( + llm_output="not cake" +) + +print(res.validated_output) # Validated outputs +# Prints "IT IS cake" +``` + ## I'm encountering an XMLSyntaxError when creating a `Guard` object from a `RAIL` specification. What should I do? Make sure that you are escaping the `&` character in your `RAIL` specification. The `&` character has a special meaning in XML, and so you need to escape it with `&`. For example, if you have a prompt like this: @@ -18,4 +89,23 @@ You need to escape the `&` character like this: ``` +## Are validators all model-based? Are they proprietary to Guardrails? + +Some validators are model based, some validators use LLMs, and some validators are purely logic. They are usually not proprietary, you can see a variety of them on the [Guardrails Hub](https://hub.guardrailsai.com) where they are largely open source and licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). + +This doesn't preclude the creation and use of custom private validators with any given technology, but we are huge believers in the power of open source software. + +## Issues loging in with `guardrails configure` + +If you encounter issues logging in using an API key with `guardrails configure`, they may be caused by one of the following: + +1. Your API key has been revoked, expired, or is invalid. You can check your existing tokens and create a new one at [https://hub.guardrailsai.com/tokens](https://hub.guardrailsai.com/tokens) if necessary. +2. If you're using Windows Powershell, ensure that you paste the token by right-clicking instead of using the keyboard shortcut `CTRL+V`, as the shortcut may cause caret characters to be pasted instead of the clipboard contents. + +If your login issues persist, please check the contents of the ~/.guardrailsrc file to ensure the correct token has been persisted. + +## Where do I get more help if I need it? + If you're still encountering issues, please [open an issue](https://github.com/guardrails-ai/guardrails/issues/new) and we'll help you out! + +We're also available on [Discord](https://discord.gg/U9RKkZSBgx) if you want to chat with us directly. diff --git a/docs/guardrails_ai/getting_started.md b/docs/guardrails_ai/getting_started.md index c6499a365..4c6cbb621 100644 --- a/docs/guardrails_ai/getting_started.md +++ b/docs/guardrails_ai/getting_started.md @@ -2,16 +2,17 @@ ## Installation +Install the Guardrails core package and CLI using pip. + ```python pip install guardrails-ai ``` ## Create Input and Output Guards for LLM Validation -1. Download and configure the Guardrails Hub CLI. +1. Configure the Guardrails Hub CLI. ```bash - pip install guardrails-ai guardrails configure ``` 2. Install a guardrail from Guardrails Hub. @@ -38,8 +39,8 @@ pip install guardrails-ai First, install the necessary guardrails from Guardrails Hub. ```bash - guardrails hub install hub://guardrails/competitor_check - guardrails hub install hub://guardrails/toxic_language + guardrails hub install hub://guardrails/regex_match + guardrails hub install hub://guardrails/valid_length ``` Then, create a Guard from the installed guardrails. @@ -48,7 +49,7 @@ pip install guardrails-ai from guardrails.hub import RegexMatch, ValidLength from guardrails import Guard - guard = Guard().use( + guard = Guard().use_many( RegexMatch(regex="^[A-Z][a-z]*$"), ValidLength(min=1, max=32) ) @@ -71,33 +72,31 @@ class Pet(BaseModel): name: str = Field(description="a unique pet name") ``` -Now, create a Guard from the `Pet` class. The Guard can be used to call the LLM in a manner so that the output is formatted to the `Pet` class. Under the hood, this is done by either of two methods: +Now, create a Guard from the `Pet` class. The Guard can be used to call the LLM in a manner so that the output is formatted to match the `Pet` class. Under the hood, this is done by either of two methods: 1. Function calling: For LLMs that support function calling, we generate structured data using the function call syntax. 2. Prompt optimization: For LLMs that don't support function calling, we add the schema of the expected output to the prompt so that the LLM can generate structured data. ```py from guardrails import Guard -import openai prompt = """ What kind of pet should I get and what should I name it? - ${gr.complete_json_suffix_v2} + ${gr.complete_xml_suffix_v2} """ -guard = Guard.from_pydantic(output_class=Pet, prompt=prompt) +guard = Guard.from_pydantic(output_class=Pet) -raw_output, validated_output, *rest = guard( - llm_api=openai.chat.completions.create, - engine="gpt-3.5-turbo" +res = guard( + messages=[{"role": "user", "content": prompt}], + model="gpt-3.5-turbo" ) -print(f"{validated_output}") +print(res.validated_output) ``` -This prints: +This prints: ``` -{ - "pet_type": "dog", - "name": "Buddy -} +{'pet_type': 'dog', 'name': 'Buddy'} ``` + +This output is a dict that matches the structure of the `Pet` class. \ No newline at end of file diff --git a/docs/guardrails_ai/installation.md b/docs/guardrails_ai/installation.md index fc206aa4a..59bdfcfcf 100644 --- a/docs/guardrails_ai/installation.md +++ b/docs/guardrails_ai/installation.md @@ -28,7 +28,7 @@ To install a specific version, run: # pip install guardrails-ai==[version-number] # Example: -pip install guardrails-ai==0.2.0a6 +pip install guardrails-ai==0.5.0a10 ``` ## Install from GitHub @@ -39,7 +39,7 @@ Installing directly from GitHub is useful when a release has not yet been cut wi # pip install git+https://github.com/guardrails-ai/guardrails.git@[branch/commit/tag] # Examples: pip install git+https://github.com/guardrails-ai/guardrails.git@main -pip install git+https://github.com/guardrails-ai/guardrails.git@dev +pip install git+https://github.com/guardrails-ai/guardrails.git@0.5.0-dev ``` diff --git a/docs/guardrails_server_api.md b/docs/guardrails_server_api.md new file mode 100644 index 000000000..50d6f41ce --- /dev/null +++ b/docs/guardrails_server_api.md @@ -0,0 +1,4704 @@ +--- +title: Guardrails Server Rest API +language_tabs: + - shell: Shell + - http: HTTP + - javascript: JavaScript + - ruby: Ruby + - python: Python + - php: PHP + - java: Java + - go: Go +toc_footers: [] +includes: [] +search: true +highlight_theme: darkula +headingLevel: 2 + +--- + + + +

Guardrails Server REST API

+:::note + +Guardrails CRUD API. The server hosts the documenation on this page in an interactive swagger UI. Typically these are available at [localhost:8000/docs](http://localhost:8000/docs) if you are running the server locally with default configurations. + +::: + +# Authentication + +- HTTP Authentication, scheme: bearer + +* API Key (ApiKeyAuth) + - Parameter Name: **authorization**, in: header. + +

Service Health

+ +## get__health-check + +`GET /health-check` + +> Example responses + +> 200 Response + +```json +{ + "status": 0, + "message": "string" +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|Returns the status of the server|[HealthCheck](#schemahealthcheck)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +

guard

+ +## getGuards + + + +`GET /guards` + +*Fetches the configuration for all Guards the user has access to.* + +> Example responses + +> 200 Response + +```json +[ + { + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] + } +] +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A list of Guards.|Inline| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[[guard](#schemaguard)]|false|none|none| +|» Guard|[guard](#schemaguard)|false|none|none| +|»» id|string(kebab-case)|true|none|The unique identifier for the Guard.| +|»» name|string|true|none|The name for the Guard.| +|»» description|string|false|none|A description that concisely states the expected behaviour or purpose of the Guard.| +|»» validators|[allOf]|false|none|none| +|»»» ValidatorReference|[ValidatorReference](#schemavalidatorreference)|false|none|none| +|»»»» id|string|true|none|The unique identifier for this Validator. Often the hub id; e.g. guardrails/regex_match| +|»»»» on|any|false|none|A reference to the property this validator should be applied against. Can be a valid JSON path or a meta-property such as "prompt" or "output"| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|string|false|none|meta-property| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|string|false|none|JSON path to property; e.g. $.foo.bar| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»» onFail|string|false|none|none| +|»» output_schema|[schema](#schemaschema)|false|none|none| +|»»» definitions|object|false|none|none| +|»»»» **additionalProperties**|any|false|none|none| +|»»» dependencies|object|false|none|none| +|»»»» **additionalProperties**|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|[string]|false|none|none| + +*allOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[core](#schemacore)|false|none|none| +|»»»» $anchor|string|false|none|none| +|»»»» $ref|string(uri-reference)|false|none|none| +|»»»» $dynamicRef|string(uri-reference)|false|none|none| +|»»»» $dynamicAnchor|string|false|none|none| +|»»»» $vocabulary|object|false|none|none| +|»»»»» **additionalProperties**|boolean|false|none|none| +|»»»» $comment|string|false|none|none| +|»»»» $defs|object|false|none|none| +|»»»»» **additionalProperties**|any|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[applicator](#schemaapplicator)|false|none|none| +|»»»» prefixItems|[any]|false|none|none| +|»»»» items|any|false|none|none| +|»»»» contains|any|false|none|none| +|»»»» additionalProperties|any|false|none|none| +|»»»» properties|object|false|none|none| +|»»»»» **additionalProperties**|any|false|none|none| +|»»»» patternProperties|object|false|none|none| +|»»»»» **additionalProperties**|any|false|none|none| +|»»»» dependentSchemas|object|false|none|none| +|»»»»» **additionalProperties**|any|false|none|none| +|»»»» propertyNames|any|false|none|none| +|»»»» if|any|false|none|none| +|»»»» then|any|false|none|none| +|»»»» else|any|false|none|none| +|»»»» allOf|[any]|false|none|none| +|»»»» anyOf|[any]|false|none|none| +|»»»» oneOf|[any]|false|none|none| +|»»»» not|any|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[unevaluated](#schemaunevaluated)|false|none|none| +|»»»» unevaluatedItems|any|false|none|none| +|»»»» unevaluatedProperties|any|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[validation](#schemavalidation)|false|none|none| +|»»»» multipleOf|number|false|none|none| +|»»»» maximum|number|false|none|none| +|»»»» exclusiveMaximum|number|false|none|none| +|»»»» minimum|number|false|none|none| +|»»»» exclusiveMinimum|number|false|none|none| +|»»»» maxLength|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» minLength|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» pattern|string(regex)|false|none|none| +|»»»» maxItems|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» minItems|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» uniqueItems|boolean|false|none|none| +|»»»» maxContains|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» minContains|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» maxProperties|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» minProperties|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|»»»» required|[string]|false|none|none| +|»»»» dependentRequired|object|false|none|none| +|»»»»» **additionalProperties**|[string]|false|none|none| +|»»»» const|any|false|none|none| +|»»»» enum|[any]|false|none|none| +|»»»» type|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|[[simpleTypes](#schemasimpletypes)]|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[meta-data](#schemameta-data)|false|none|none| +|»»»» title|string|false|none|none| +|»»»» description|string|false|none|none| +|»»»» default|any|false|none|none| +|»»»» deprecated|boolean|false|none|none| +|»»»» readOnly|boolean|false|none|none| +|»»»» writeOnly|boolean|false|none|none| +|»»»» examples|[any]|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[format-annotation](#schemaformat-annotation)|false|none|none| +|»»»» format|string|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[content](#schemacontent)|false|none|none| +|»»»» contentMediaType|string|false|none|none| +|»»»» contentEncoding|string|false|none|none| +|»»»» contentSchema|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»» history|[[call](#schemacall)]|false|read-only|none| +|»»» Call|[call](#schemacall)|false|none|none| +|»»»» id|string|true|none|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»»» iterations|[[iteration](#schemaiteration)]|false|none|none| +|»»»»» Iteration|[iteration](#schemaiteration)|false|none|none| +|»»»»»» id|string|true|none|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»»»»» index|integer|true|none|The zero-based index of this iteration within the current Call.| +|»»»»»» callId|string|true|none|The unique identifier for the Call that this iteration is a part of.| +|»»»»»» inputs|[inputs](#schemainputs)|false|none|none| +|»»»»»»» llmApi|string|false|none|The LLM resource targeted by the user. e.g. openai.chat.completions.create| +|»»»»»»» llmOutput|string|false|none|The string output from an external LLM call provided by the user via Guard.parse.| +|»»»»»»» instructions|string|false|none|The instructions for chat models.| +|»»»»»»» prompt|string|false|none|The prompt for the LLM.| +|»»»»»»» msgHistory|[object]|false|none|The message history for chat models.| +|»»»»»»»» **additionalProperties**|any|false|none|none| +|»»»»»»» promptParams|object|false|none|Parameters to be formatted into the prompt.| +|»»»»»»»» **additionalProperties**|any|false|none|none| +|»»»»»»» numReasks|integer|false|none|The total number of times the LLM can be called to correct output excluding the initial call.| +|»»»»»»» metadata|object|false|none|Additional data to be used by Validators during execution time.| +|»»»»»»»» **additionalProperties**|any|false|none|none| +|»»»»»»» fullSchemaReask|boolean|false|none|Whether to perform reasks for the entire schema rather than for individual fields.| +|»»»»»»» stream|boolean|false|none|Whether to use streaming.| +|»»»»»» outputs|[outputs](#schemaoutputs)|false|none|none| +|»»»»»»» llmResponseInfo|[LLMResponse](#schemallmresponse)|false|none|Information from the LLM response.| +|»»»»»»»» promptTokenCount|integer|false|none|none| +|»»»»»»»» responseTokenCount|integer|false|none|none| +|»»»»»»»» output|string|true|none|none| +|»»»»»»»» streamOutput|[string]|false|none|none| +|»»»»»»»» asyncStreamOutput|[string]|false|none|none| +|»»»»»»» rawOutput|string|false|none|The string content from the LLM response.| +|»»»»»»» parsedOutput|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|object|false|none|none| +|»»»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[anyOf]|false|none|none| +|»»»»»»»»» AnyType|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|boolean|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|integer|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|null|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|number|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|[objects](#schemaobjects)|false|none|none| +|»»»»»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|[anyOf]|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»»» *anonymous*|[objects](#schemaobjects)|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»» validationResponse|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[reask](#schemareask)|false|none|none| +|»»»»»»»»» **additionalProperties**|any|false|none|none| +|»»»»»»»»» incorrectValue|any|false|none|none| +|»»»»»»»»» failResults|[allOf]|false|none|none| +|»»»»»»»»»» FailResult|[fail-result](#schemafail-result)|false|none|The output from a single Validator.| +|»»»»»»»»»»» outcome|any|true|none|none| +|»»»»»»»»»»» errorMessage|string|true|none|none| +|»»»»»»»»»»» fixValue|any|false|none|none| +|»»»»»»»»»»» errorSpans|[[error-span](#schemaerror-span)]|false|none|none| +|»»»»»»»»»»»» ErrorSpan|[error-span](#schemaerror-span)|false|none|none| +|»»»»»»»»»»»»» start|integer|true|none|none| +|»»»»»»»»»»»»» end|integer|true|none|none| +|»»»»»»»»»»»»» reason|string|true|none|The reason validation failed, specific to this chunk.| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|object|false|none|none| +|»»»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[anyOf]|false|none|none| +|»»»»»»»»» AnyType|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»» guardedOutput|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|object|false|none|none| +|»»»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[anyOf]|false|none|none| +|»»»»»»»»» AnyType|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»» reasks|[[reask](#schemareask)]|false|none|none| +|»»»»»»»» ReAsk|[reask](#schemareask)|false|none|none| +|»»»»»»» validatorLogs|[[validator-log](#schemavalidator-log)]|false|none|none| +|»»»»»»»» ValidatorLog|[validator-log](#schemavalidator-log)|false|none|none| +|»»»»»»»»» validatorName|string(PascalCase)|true|none|The class name of the validator.| +|»»»»»»»»» registeredName|string(kebab-case)|true|none|The registry id of the validator.| +|»»»»»»»»» instanceId|any|false|none|A unique identifier for the validator that produced this log within the session.| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|integer|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» propertyPath|string|true|none|The JSON path to the property which was validated that produced this log.| +|»»»»»»»»» valueBeforeValidation|any|true|none|none| +|»»»»»»»»» valueAfterValidation|any|false|none|none| +|»»»»»»»»» validationResult|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|[pass-result](#schemapass-result)|false|none|The output from a single Validator.| +|»»»»»»»»»»» outcome|any|true|none|none| +|»»»»»»»»»»» valueOverride|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»»» *anonymous*|[fail-result](#schemafail-result)|false|none|The output from a single Validator.| +|»»»»»»»»»»» outcome|any|true|none|none| +|»»»»»»»»»»» errorMessage|string|true|none|none| +|»»»»»»»»»»» fixValue|any|false|none|none| +|»»»»»»»»»»» errorSpans|[[error-span](#schemaerror-span)]|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» startTime|string(date-time)|false|none|none| +|»»»»»»»»» endTime|string(date-time)|false|none|none| +|»»»»»»» error|string|false|none|The error message from any exception which interrupted the Guard execution process.| +|»»»» inputs|[CallInputs](#schemacallinputs)|false|none|none| + +*allOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|[inputs](#schemainputs)|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» *anonymous*|[args-and-kwargs](#schemaargs-and-kwargs)|false|none|none| +|»»»»»» args|[anyOf]|false|none|none| +|»»»»»»» AnyType|any|false|none|none| +|»»»»»» kwargs|object|false|none|none| +|»»»»»»» **additionalProperties**|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»» exception|string|false|none|none| + +#### Enumerated Values + +|Property|Value| +|---|---| +|*anonymous*|prompt| +|*anonymous*|instructions| +|*anonymous*|msg_history| +|*anonymous*|messages| +|*anonymous*|output| +|onFail|exception| +|onFail|filter| +|onFail|fix| +|onFail|fix_reask| +|onFail|noop| +|onFail|reask| +|onFail|refrain| +|onFail|custom| +|*anonymous*|array| +|*anonymous*|boolean| +|*anonymous*|integer| +|*anonymous*|null| +|*anonymous*|number| +|*anonymous*|object| +|*anonymous*|string| + + + +## createGuard + + + +`POST /guards` + +*Creates a Guard* + +> Body parameter + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + } +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|body|body|[guard](#schemaguard)|true|none| +|» id|body|string(kebab-case)|true|The unique identifier for the Guard.| +|» name|body|string|true|The name for the Guard.| +|» description|body|string|false|A description that concisely states the expected behaviour or purpose of the Guard.| +|» validators|body|[allOf]|false|none| +|»» ValidatorReference|body|[ValidatorReference](#schemavalidatorreference)|false|none| +|»»» id|body|string|true|The unique identifier for this Validator. Often the hub id; e.g. guardrails/regex_match| +|»»» on|body|any|false|A reference to the property this validator should be applied against. Can be a valid JSON path or a meta-property such as "prompt" or "output"| +|»»»» *anonymous*|body|string|false|meta-property| +|»»»» *anonymous*|body|string|false|JSON path to property; e.g. $.foo.bar| +|»»» onFail|body|string|false|none| +|» output_schema|body|[schema](#schemaschema)|false|none| +|»» definitions|body|object|false|none| +|»»» **additionalProperties**|body|any|false|none| +|»» dependencies|body|object|false|none| +|»»» **additionalProperties**|body|any|false|none| +|»»»» *anonymous*|body|any|false|none| +|»»»» *anonymous*|body|[string]|false|none| +|»» *anonymous*|body|[core](#schemacore)|false|none| +|»»» $anchor|body|string|false|none| +|»»» $ref|body|string(uri-reference)|false|none| +|»»» $dynamicRef|body|string(uri-reference)|false|none| +|»»» $dynamicAnchor|body|string|false|none| +|»»» $vocabulary|body|object|false|none| +|»»»» **additionalProperties**|body|boolean|false|none| +|»»» $comment|body|string|false|none| +|»»» $defs|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»» *anonymous*|body|[applicator](#schemaapplicator)|false|none| +|»»» prefixItems|body|[any]|false|none| +|»»» items|body|any|false|none| +|»»» contains|body|any|false|none| +|»»» additionalProperties|body|any|false|none| +|»»» properties|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»»» patternProperties|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»»» dependentSchemas|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»»» propertyNames|body|any|false|none| +|»»» if|body|any|false|none| +|»»» then|body|any|false|none| +|»»» else|body|any|false|none| +|»»» allOf|body|[any]|false|none| +|»»» anyOf|body|[any]|false|none| +|»»» oneOf|body|[any]|false|none| +|»»» not|body|any|false|none| +|»» *anonymous*|body|[unevaluated](#schemaunevaluated)|false|none| +|»»» unevaluatedItems|body|any|false|none| +|»»» unevaluatedProperties|body|any|false|none| +|»» *anonymous*|body|[validation](#schemavalidation)|false|none| +|»»» multipleOf|body|number|false|none| +|»»» maximum|body|number|false|none| +|»»» exclusiveMaximum|body|number|false|none| +|»»» minimum|body|number|false|none| +|»»» exclusiveMinimum|body|number|false|none| +|»»» maxLength|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minLength|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» pattern|body|string(regex)|false|none| +|»»» maxItems|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minItems|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» uniqueItems|body|boolean|false|none| +|»»» maxContains|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minContains|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» maxProperties|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minProperties|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» required|body|[string]|false|none| +|»»» dependentRequired|body|object|false|none| +|»»»» **additionalProperties**|body|[string]|false|none| +|»»» const|body|any|false|none| +|»»» enum|body|[any]|false|none| +|»»» type|body|any|false|none| +|»»»» *anonymous*|body|any|false|none| +|»»»» *anonymous*|body|[[simpleTypes](#schemasimpletypes)]|false|none| +|»» *anonymous*|body|[meta-data](#schemameta-data)|false|none| +|»»» title|body|string|false|none| +|»»» description|body|string|false|none| +|»»» default|body|any|false|none| +|»»» deprecated|body|boolean|false|none| +|»»» readOnly|body|boolean|false|none| +|»»» writeOnly|body|boolean|false|none| +|»»» examples|body|[any]|false|none| +|»» *anonymous*|body|[format-annotation](#schemaformat-annotation)|false|none| +|»»» format|body|string|false|none| +|»» *anonymous*|body|[content](#schemacontent)|false|none| +|»»» contentMediaType|body|string|false|none| +|»»» contentEncoding|body|string|false|none| +|»»» contentSchema|body|any|false|none| +|» history|body|[[call](#schemacall)]|false|none| +|»» Call|body|[call](#schemacall)|false|none| +|»»» id|body|string|true|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»» iterations|body|[[iteration](#schemaiteration)]|false|none| +|»»»» Iteration|body|[iteration](#schemaiteration)|false|none| +|»»»»» id|body|string|true|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»»»» index|body|integer|true|The zero-based index of this iteration within the current Call.| +|»»»»» callId|body|string|true|The unique identifier for the Call that this iteration is a part of.| +|»»»»» inputs|body|[inputs](#schemainputs)|false|none| +|»»»»»» llmApi|body|string|false|The LLM resource targeted by the user. e.g. openai.chat.completions.create| +|»»»»»» llmOutput|body|string|false|The string output from an external LLM call provided by the user via Guard.parse.| +|»»»»»» instructions|body|string|false|The instructions for chat models.| +|»»»»»» prompt|body|string|false|The prompt for the LLM.| +|»»»»»» msgHistory|body|[object]|false|The message history for chat models.| +|»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»» promptParams|body|object|false|Parameters to be formatted into the prompt.| +|»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»» numReasks|body|integer|false|The total number of times the LLM can be called to correct output excluding the initial call.| +|»»»»»» metadata|body|object|false|Additional data to be used by Validators during execution time.| +|»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»» fullSchemaReask|body|boolean|false|Whether to perform reasks for the entire schema rather than for individual fields.| +|»»»»»» stream|body|boolean|false|Whether to use streaming.| +|»»»»» outputs|body|[outputs](#schemaoutputs)|false|none| +|»»»»»» llmResponseInfo|body|[LLMResponse](#schemallmresponse)|false|Information from the LLM response.| +|»»»»»»» promptTokenCount|body|integer|false|none| +|»»»»»»» responseTokenCount|body|integer|false|none| +|»»»»»»» output|body|string|true|none| +|»»»»»»» streamOutput|body|[string]|false|none| +|»»»»»»» asyncStreamOutput|body|[string]|false|none| +|»»»»»» rawOutput|body|string|false|The string content from the LLM response.| +|»»»»»» parsedOutput|body|any|false|none| +|»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»» *anonymous*|body|object|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»» AnyType|body|any|false|none| +|»»»»»»»»» *anonymous*|body|any|false|none| +|»»»»»»»»»» *anonymous*|body|boolean|false|none| +|»»»»»»»»»» *anonymous*|body|integer|false|none| +|»»»»»»»»»» *anonymous*|body|null|false|none| +|»»»»»»»»»» *anonymous*|body|number|false|none| +|»»»»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»»»» *anonymous*|body|[objects](#schemaobjects)|false|none| +|»»»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»»»» *anonymous*|body|any|false|none| +|»»»»»»»»»» *anonymous*|body|[objects](#schemaobjects)|false|none| +|»»»»»» validationResponse|body|any|false|none| +|»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»» *anonymous*|body|[reask](#schemareask)|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»»» incorrectValue|body|any|false|none| +|»»»»»»»» failResults|body|[allOf]|false|none| +|»»»»»»»»» FailResult|body|[fail-result](#schemafail-result)|false|The output from a single Validator.| +|»»»»»»»»»» outcome|body|any|true|none| +|»»»»»»»»»» errorMessage|body|string|true|none| +|»»»»»»»»»» fixValue|body|any|false|none| +|»»»»»»»»»» errorSpans|body|[[error-span](#schemaerror-span)]|false|none| +|»»»»»»»»»»» ErrorSpan|body|[error-span](#schemaerror-span)|false|none| +|»»»»»»»»»»»» start|body|integer|true|none| +|»»»»»»»»»»»» end|body|integer|true|none| +|»»»»»»»»»»»» reason|body|string|true|The reason validation failed, specific to this chunk.| +|»»»»»»» *anonymous*|body|object|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»» AnyType|body|any|false|none| +|»»»»»» guardedOutput|body|any|false|none| +|»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»» *anonymous*|body|object|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»» AnyType|body|any|false|none| +|»»»»»» reasks|body|[[reask](#schemareask)]|false|none| +|»»»»»»» ReAsk|body|[reask](#schemareask)|false|none| +|»»»»»» validatorLogs|body|[[validator-log](#schemavalidator-log)]|false|none| +|»»»»»»» ValidatorLog|body|[validator-log](#schemavalidator-log)|false|none| +|»»»»»»»» validatorName|body|string(PascalCase)|true|The class name of the validator.| +|»»»»»»»» registeredName|body|string(kebab-case)|true|The registry id of the validator.| +|»»»»»»»» instanceId|body|any|false|A unique identifier for the validator that produced this log within the session.| +|»»»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»»»» *anonymous*|body|integer|false|none| +|»»»»»»»» propertyPath|body|string|true|The JSON path to the property which was validated that produced this log.| +|»»»»»»»» valueBeforeValidation|body|any|true|none| +|»»»»»»»» valueAfterValidation|body|any|false|none| +|»»»»»»»» validationResult|body|any|false|none| +|»»»»»»»»» *anonymous*|body|[pass-result](#schemapass-result)|false|The output from a single Validator.| +|»»»»»»»»»» outcome|body|any|true|none| +|»»»»»»»»»» valueOverride|body|any|false|none| +|»»»»»»»»» *anonymous*|body|[fail-result](#schemafail-result)|false|The output from a single Validator.| +|»»»»»»»»»» outcome|body|any|true|none| +|»»»»»»»»»» errorMessage|body|string|true|none| +|»»»»»»»»»» fixValue|body|any|false|none| +|»»»»»»»»»» errorSpans|body|[[error-span](#schemaerror-span)]|false|none| +|»»»»»»»» startTime|body|string(date-time)|false|none| +|»»»»»»»» endTime|body|string(date-time)|false|none| +|»»»»»» error|body|string|false|The error message from any exception which interrupted the Guard execution process.| +|»»» inputs|body|[CallInputs](#schemacallinputs)|false|none| +|»»»» *anonymous*|body|[inputs](#schemainputs)|false|none| +|»»»» *anonymous*|body|[args-and-kwargs](#schemaargs-and-kwargs)|false|none| +|»»»»» args|body|[anyOf]|false|none| +|»»»»»» AnyType|body|any|false|none| +|»»»»» kwargs|body|object|false|none| +|»»»»»» **additionalProperties**|body|any|false|none| +|»»» exception|body|string|false|none| + +#### Enumerated Values + +|Parameter|Value| +|---|---| +|»»»» *anonymous*|prompt| +|»»»» *anonymous*|instructions| +|»»»» *anonymous*|msg_history| +|»»»» *anonymous*|messages| +|»»»» *anonymous*|output| +|»»» onFail|exception| +|»»» onFail|filter| +|»»» onFail|fix| +|»»» onFail|fix_reask| +|»»» onFail|noop| +|»»» onFail|reask| +|»»» onFail|refrain| +|»»» onFail|custom| +|»»»» *anonymous*|array| +|»»»» *anonymous*|boolean| +|»»»» *anonymous*|integer| +|»»»» *anonymous*|null| +|»»»» *anonymous*|number| +|»»»» *anonymous*|object| +|»»»» *anonymous*|string| +|»»»» *anonymous*|array| +|»»»» *anonymous*|boolean| +|»»»» *anonymous*|integer| +|»»»» *anonymous*|null| +|»»»» *anonymous*|number| +|»»»» *anonymous*|object| +|»»»» *anonymous*|string| + +> Example responses + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|the new Guard|[guard](#schemaguard)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +## getGuard + + + +`GET /guards/{guardName}` + +*Fetches a specific Guard* + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|guardName|path|string|true|Guard name| +|asOf|query|string(date-time)|false|Used to query for data as it existed at this date and time| + +> Example responses + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|the fetched Guard|[guard](#schemaguard)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +## updateGuard + + + +`PUT /guards/{guardName}` + +*Updates a Guard* + +> Body parameter + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + } +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|guardName|path|string|true|Guard name| +|body|body|[guard](#schemaguard)|true|none| +|» id|body|string(kebab-case)|true|The unique identifier for the Guard.| +|» name|body|string|true|The name for the Guard.| +|» description|body|string|false|A description that concisely states the expected behaviour or purpose of the Guard.| +|» validators|body|[allOf]|false|none| +|»» ValidatorReference|body|[ValidatorReference](#schemavalidatorreference)|false|none| +|»»» id|body|string|true|The unique identifier for this Validator. Often the hub id; e.g. guardrails/regex_match| +|»»» on|body|any|false|A reference to the property this validator should be applied against. Can be a valid JSON path or a meta-property such as "prompt" or "output"| +|»»»» *anonymous*|body|string|false|meta-property| +|»»»» *anonymous*|body|string|false|JSON path to property; e.g. $.foo.bar| +|»»» onFail|body|string|false|none| +|» output_schema|body|[schema](#schemaschema)|false|none| +|»» definitions|body|object|false|none| +|»»» **additionalProperties**|body|any|false|none| +|»» dependencies|body|object|false|none| +|»»» **additionalProperties**|body|any|false|none| +|»»»» *anonymous*|body|any|false|none| +|»»»» *anonymous*|body|[string]|false|none| +|»» *anonymous*|body|[core](#schemacore)|false|none| +|»»» $anchor|body|string|false|none| +|»»» $ref|body|string(uri-reference)|false|none| +|»»» $dynamicRef|body|string(uri-reference)|false|none| +|»»» $dynamicAnchor|body|string|false|none| +|»»» $vocabulary|body|object|false|none| +|»»»» **additionalProperties**|body|boolean|false|none| +|»»» $comment|body|string|false|none| +|»»» $defs|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»» *anonymous*|body|[applicator](#schemaapplicator)|false|none| +|»»» prefixItems|body|[any]|false|none| +|»»» items|body|any|false|none| +|»»» contains|body|any|false|none| +|»»» additionalProperties|body|any|false|none| +|»»» properties|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»»» patternProperties|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»»» dependentSchemas|body|object|false|none| +|»»»» **additionalProperties**|body|any|false|none| +|»»» propertyNames|body|any|false|none| +|»»» if|body|any|false|none| +|»»» then|body|any|false|none| +|»»» else|body|any|false|none| +|»»» allOf|body|[any]|false|none| +|»»» anyOf|body|[any]|false|none| +|»»» oneOf|body|[any]|false|none| +|»»» not|body|any|false|none| +|»» *anonymous*|body|[unevaluated](#schemaunevaluated)|false|none| +|»»» unevaluatedItems|body|any|false|none| +|»»» unevaluatedProperties|body|any|false|none| +|»» *anonymous*|body|[validation](#schemavalidation)|false|none| +|»»» multipleOf|body|number|false|none| +|»»» maximum|body|number|false|none| +|»»» exclusiveMaximum|body|number|false|none| +|»»» minimum|body|number|false|none| +|»»» exclusiveMinimum|body|number|false|none| +|»»» maxLength|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minLength|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» pattern|body|string(regex)|false|none| +|»»» maxItems|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minItems|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» uniqueItems|body|boolean|false|none| +|»»» maxContains|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minContains|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» maxProperties|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» minProperties|body|[nonNegativeInteger](#schemanonnegativeinteger)|false|none| +|»»» required|body|[string]|false|none| +|»»» dependentRequired|body|object|false|none| +|»»»» **additionalProperties**|body|[string]|false|none| +|»»» const|body|any|false|none| +|»»» enum|body|[any]|false|none| +|»»» type|body|any|false|none| +|»»»» *anonymous*|body|any|false|none| +|»»»» *anonymous*|body|[[simpleTypes](#schemasimpletypes)]|false|none| +|»» *anonymous*|body|[meta-data](#schemameta-data)|false|none| +|»»» title|body|string|false|none| +|»»» description|body|string|false|none| +|»»» default|body|any|false|none| +|»»» deprecated|body|boolean|false|none| +|»»» readOnly|body|boolean|false|none| +|»»» writeOnly|body|boolean|false|none| +|»»» examples|body|[any]|false|none| +|»» *anonymous*|body|[format-annotation](#schemaformat-annotation)|false|none| +|»»» format|body|string|false|none| +|»» *anonymous*|body|[content](#schemacontent)|false|none| +|»»» contentMediaType|body|string|false|none| +|»»» contentEncoding|body|string|false|none| +|»»» contentSchema|body|any|false|none| +|» history|body|[[call](#schemacall)]|false|none| +|»» Call|body|[call](#schemacall)|false|none| +|»»» id|body|string|true|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»» iterations|body|[[iteration](#schemaiteration)]|false|none| +|»»»» Iteration|body|[iteration](#schemaiteration)|false|none| +|»»»»» id|body|string|true|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»»»» index|body|integer|true|The zero-based index of this iteration within the current Call.| +|»»»»» callId|body|string|true|The unique identifier for the Call that this iteration is a part of.| +|»»»»» inputs|body|[inputs](#schemainputs)|false|none| +|»»»»»» llmApi|body|string|false|The LLM resource targeted by the user. e.g. openai.chat.completions.create| +|»»»»»» llmOutput|body|string|false|The string output from an external LLM call provided by the user via Guard.parse.| +|»»»»»» instructions|body|string|false|The instructions for chat models.| +|»»»»»» prompt|body|string|false|The prompt for the LLM.| +|»»»»»» msgHistory|body|[object]|false|The message history for chat models.| +|»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»» promptParams|body|object|false|Parameters to be formatted into the prompt.| +|»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»» numReasks|body|integer|false|The total number of times the LLM can be called to correct output excluding the initial call.| +|»»»»»» metadata|body|object|false|Additional data to be used by Validators during execution time.| +|»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»» fullSchemaReask|body|boolean|false|Whether to perform reasks for the entire schema rather than for individual fields.| +|»»»»»» stream|body|boolean|false|Whether to use streaming.| +|»»»»» outputs|body|[outputs](#schemaoutputs)|false|none| +|»»»»»» llmResponseInfo|body|[LLMResponse](#schemallmresponse)|false|Information from the LLM response.| +|»»»»»»» promptTokenCount|body|integer|false|none| +|»»»»»»» responseTokenCount|body|integer|false|none| +|»»»»»»» output|body|string|true|none| +|»»»»»»» streamOutput|body|[string]|false|none| +|»»»»»»» asyncStreamOutput|body|[string]|false|none| +|»»»»»» rawOutput|body|string|false|The string content from the LLM response.| +|»»»»»» parsedOutput|body|any|false|none| +|»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»» *anonymous*|body|object|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»» AnyType|body|any|false|none| +|»»»»»»»»» *anonymous*|body|any|false|none| +|»»»»»»»»»» *anonymous*|body|boolean|false|none| +|»»»»»»»»»» *anonymous*|body|integer|false|none| +|»»»»»»»»»» *anonymous*|body|null|false|none| +|»»»»»»»»»» *anonymous*|body|number|false|none| +|»»»»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»»»» *anonymous*|body|[objects](#schemaobjects)|false|none| +|»»»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»»»» *anonymous*|body|any|false|none| +|»»»»»»»»»» *anonymous*|body|[objects](#schemaobjects)|false|none| +|»»»»»» validationResponse|body|any|false|none| +|»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»» *anonymous*|body|[reask](#schemareask)|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»»» incorrectValue|body|any|false|none| +|»»»»»»»» failResults|body|[allOf]|false|none| +|»»»»»»»»» FailResult|body|[fail-result](#schemafail-result)|false|The output from a single Validator.| +|»»»»»»»»»» outcome|body|any|true|none| +|»»»»»»»»»» errorMessage|body|string|true|none| +|»»»»»»»»»» fixValue|body|any|false|none| +|»»»»»»»»»» errorSpans|body|[[error-span](#schemaerror-span)]|false|none| +|»»»»»»»»»»» ErrorSpan|body|[error-span](#schemaerror-span)|false|none| +|»»»»»»»»»»»» start|body|integer|true|none| +|»»»»»»»»»»»» end|body|integer|true|none| +|»»»»»»»»»»»» reason|body|string|true|The reason validation failed, specific to this chunk.| +|»»»»»»» *anonymous*|body|object|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»» AnyType|body|any|false|none| +|»»»»»» guardedOutput|body|any|false|none| +|»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»» *anonymous*|body|object|false|none| +|»»»»»»»» **additionalProperties**|body|any|false|none| +|»»»»»»» *anonymous*|body|[anyOf]|false|none| +|»»»»»»»» AnyType|body|any|false|none| +|»»»»»» reasks|body|[[reask](#schemareask)]|false|none| +|»»»»»»» ReAsk|body|[reask](#schemareask)|false|none| +|»»»»»» validatorLogs|body|[[validator-log](#schemavalidator-log)]|false|none| +|»»»»»»» ValidatorLog|body|[validator-log](#schemavalidator-log)|false|none| +|»»»»»»»» validatorName|body|string(PascalCase)|true|The class name of the validator.| +|»»»»»»»» registeredName|body|string(kebab-case)|true|The registry id of the validator.| +|»»»»»»»» instanceId|body|any|false|A unique identifier for the validator that produced this log within the session.| +|»»»»»»»»» *anonymous*|body|string|false|none| +|»»»»»»»»» *anonymous*|body|integer|false|none| +|»»»»»»»» propertyPath|body|string|true|The JSON path to the property which was validated that produced this log.| +|»»»»»»»» valueBeforeValidation|body|any|true|none| +|»»»»»»»» valueAfterValidation|body|any|false|none| +|»»»»»»»» validationResult|body|any|false|none| +|»»»»»»»»» *anonymous*|body|[pass-result](#schemapass-result)|false|The output from a single Validator.| +|»»»»»»»»»» outcome|body|any|true|none| +|»»»»»»»»»» valueOverride|body|any|false|none| +|»»»»»»»»» *anonymous*|body|[fail-result](#schemafail-result)|false|The output from a single Validator.| +|»»»»»»»»»» outcome|body|any|true|none| +|»»»»»»»»»» errorMessage|body|string|true|none| +|»»»»»»»»»» fixValue|body|any|false|none| +|»»»»»»»»»» errorSpans|body|[[error-span](#schemaerror-span)]|false|none| +|»»»»»»»» startTime|body|string(date-time)|false|none| +|»»»»»»»» endTime|body|string(date-time)|false|none| +|»»»»»» error|body|string|false|The error message from any exception which interrupted the Guard execution process.| +|»»» inputs|body|[CallInputs](#schemacallinputs)|false|none| +|»»»» *anonymous*|body|[inputs](#schemainputs)|false|none| +|»»»» *anonymous*|body|[args-and-kwargs](#schemaargs-and-kwargs)|false|none| +|»»»»» args|body|[anyOf]|false|none| +|»»»»»» AnyType|body|any|false|none| +|»»»»» kwargs|body|object|false|none| +|»»»»»» **additionalProperties**|body|any|false|none| +|»»» exception|body|string|false|none| + +#### Enumerated Values + +|Parameter|Value| +|---|---| +|»»»» *anonymous*|prompt| +|»»»» *anonymous*|instructions| +|»»»» *anonymous*|msg_history| +|»»»» *anonymous*|messages| +|»»»» *anonymous*|output| +|»»» onFail|exception| +|»»» onFail|filter| +|»»» onFail|fix| +|»»» onFail|fix_reask| +|»»» onFail|noop| +|»»» onFail|reask| +|»»» onFail|refrain| +|»»» onFail|custom| +|»»»» *anonymous*|array| +|»»»» *anonymous*|boolean| +|»»»» *anonymous*|integer| +|»»»» *anonymous*|null| +|»»»» *anonymous*|number| +|»»»» *anonymous*|object| +|»»»» *anonymous*|string| +|»»»» *anonymous*|array| +|»»»» *anonymous*|boolean| +|»»»» *anonymous*|integer| +|»»»» *anonymous*|null| +|»»»» *anonymous*|number| +|»»»» *anonymous*|object| +|»»»» *anonymous*|string| + +> Example responses + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|the updated Guard|[guard](#schemaguard)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +## deleteGuard + + + +`DELETE /guards/{guardName}` + +*Deletes a Guard* + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|guardName|path|string|true|Guard name| + +> Example responses + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|the deleted Guard|[guard](#schemaguard)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +## getGuardHistory + + + +`GET /guards/{guardName}/history/{callId}` + +*Fetches the history for a specific Guard execution by using the id for the most recent Call* + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|guardName|path|string|true|Guard name| +|callId|path|string|true|Call id| + +> Example responses + +> 200 Response + +```json +[ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } +] +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|the fetched Guard History|Inline| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + +

Response Schema

+ +Status Code **200** + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[[call](#schemacall)]|false|none|none| +|» Call|[call](#schemacall)|false|none|none| +|»» id|string|true|none|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»» iterations|[[iteration](#schemaiteration)]|false|none|none| +|»»» Iteration|[iteration](#schemaiteration)|false|none|none| +|»»»» id|string|true|none|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|»»»» index|integer|true|none|The zero-based index of this iteration within the current Call.| +|»»»» callId|string|true|none|The unique identifier for the Call that this iteration is a part of.| +|»»»» inputs|[inputs](#schemainputs)|false|none|none| +|»»»»» llmApi|string|false|none|The LLM resource targeted by the user. e.g. openai.chat.completions.create| +|»»»»» llmOutput|string|false|none|The string output from an external LLM call provided by the user via Guard.parse.| +|»»»»» instructions|string|false|none|The instructions for chat models.| +|»»»»» prompt|string|false|none|The prompt for the LLM.| +|»»»»» msgHistory|[object]|false|none|The message history for chat models.| +|»»»»»» **additionalProperties**|any|false|none|none| +|»»»»» promptParams|object|false|none|Parameters to be formatted into the prompt.| +|»»»»»» **additionalProperties**|any|false|none|none| +|»»»»» numReasks|integer|false|none|The total number of times the LLM can be called to correct output excluding the initial call.| +|»»»»» metadata|object|false|none|Additional data to be used by Validators during execution time.| +|»»»»»» **additionalProperties**|any|false|none|none| +|»»»»» fullSchemaReask|boolean|false|none|Whether to perform reasks for the entire schema rather than for individual fields.| +|»»»»» stream|boolean|false|none|Whether to use streaming.| +|»»»» outputs|[outputs](#schemaoutputs)|false|none|none| +|»»»»» llmResponseInfo|[LLMResponse](#schemallmresponse)|false|none|Information from the LLM response.| +|»»»»»» promptTokenCount|integer|false|none|none| +|»»»»»» responseTokenCount|integer|false|none|none| +|»»»»»» output|string|true|none|none| +|»»»»»» streamOutput|[string]|false|none|none| +|»»»»»» asyncStreamOutput|[string]|false|none|none| +|»»»»» rawOutput|string|false|none|The string content from the LLM response.| +|»»»»» parsedOutput|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|object|false|none|none| +|»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|[anyOf]|false|none|none| +|»»»»»»» AnyType|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|boolean|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|integer|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|null|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|number|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[objects](#schemaobjects)|false|none|none| +|»»»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[anyOf]|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»»» *anonymous*|[objects](#schemaobjects)|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» validationResponse|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|[reask](#schemareask)|false|none|none| +|»»»»»»» **additionalProperties**|any|false|none|none| +|»»»»»»» incorrectValue|any|false|none|none| +|»»»»»»» failResults|[allOf]|false|none|none| +|»»»»»»»» FailResult|[fail-result](#schemafail-result)|false|none|The output from a single Validator.| +|»»»»»»»»» outcome|any|true|none|none| +|»»»»»»»»» errorMessage|string|true|none|none| +|»»»»»»»»» fixValue|any|false|none|none| +|»»»»»»»»» errorSpans|[[error-span](#schemaerror-span)]|false|none|none| +|»»»»»»»»»» ErrorSpan|[error-span](#schemaerror-span)|false|none|none| +|»»»»»»»»»»» start|integer|true|none|none| +|»»»»»»»»»»» end|integer|true|none|none| +|»»»»»»»»»»» reason|string|true|none|The reason validation failed, specific to this chunk.| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|object|false|none|none| +|»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|[anyOf]|false|none|none| +|»»»»»»» AnyType|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» guardedOutput|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|object|false|none|none| +|»»»»»»» **additionalProperties**|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»» *anonymous*|[anyOf]|false|none|none| +|»»»»»»» AnyType|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»» reasks|[[reask](#schemareask)]|false|none|none| +|»»»»»» ReAsk|[reask](#schemareask)|false|none|none| +|»»»»» validatorLogs|[[validator-log](#schemavalidator-log)]|false|none|none| +|»»»»»» ValidatorLog|[validator-log](#schemavalidator-log)|false|none|none| +|»»»»»»» validatorName|string(PascalCase)|true|none|The class name of the validator.| +|»»»»»»» registeredName|string(kebab-case)|true|none|The registry id of the validator.| +|»»»»»»» instanceId|any|false|none|A unique identifier for the validator that produced this log within the session.| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|string|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|integer|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»» propertyPath|string|true|none|The JSON path to the property which was validated that produced this log.| +|»»»»»»» valueBeforeValidation|any|true|none|none| +|»»»»»»» valueAfterValidation|any|false|none|none| +|»»»»»»» validationResult|any|false|none|none| + +*anyOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[pass-result](#schemapass-result)|false|none|The output from a single Validator.| +|»»»»»»»»» outcome|any|true|none|none| +|»»»»»»»»» valueOverride|any|false|none|none| + +*or* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»»» *anonymous*|[fail-result](#schemafail-result)|false|none|The output from a single Validator.| +|»»»»»»»»» outcome|any|true|none|none| +|»»»»»»»»» errorMessage|string|true|none|none| +|»»»»»»»»» fixValue|any|false|none|none| +|»»»»»»»»» errorSpans|[[error-span](#schemaerror-span)]|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»»»»»» startTime|string(date-time)|false|none|none| +|»»»»»»» endTime|string(date-time)|false|none|none| +|»»»»» error|string|false|none|The error message from any exception which interrupted the Guard execution process.| +|»» inputs|[CallInputs](#schemacallinputs)|false|none|none| + +*allOf* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[inputs](#schemainputs)|false|none|none| + +*and* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»»» *anonymous*|[args-and-kwargs](#schemaargs-and-kwargs)|false|none|none| +|»»»» args|[anyOf]|false|none|none| +|»»»»» AnyType|any|false|none|none| +|»»»» kwargs|object|false|none|none| +|»»»»» **additionalProperties**|any|false|none|none| + +*continued* + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»» exception|string|false|none|none| + + + +

openai

+ +## openaiChatCompletion + + + +`POST /guards/{guardName}/openai/v1/chat/completions` + +*OpenAI SDK compatible endpoint for Chat Completions* + +> Body parameter + +```json +{ + "model": "gpt-3.5-turbo", + "messages": [ + { + "role": "string", + "content": "string" + } + ], + "max_tokens": 0, + "temperature": 0 +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|guardName|path|string|true|Guard name| +|body|body|[OpenAIChatCompletionPayload](#schemaopenaichatcompletionpayload)|true|none| +|» model|body|string|false|The model to use for the completion| +|» messages|body|[object]|false|The messages to use for the completion| +|»» role|body|string|false|The role of the message| +|»» content|body|string|false|The content of the message| +|» max_tokens|body|integer|false|The maximum number of tokens to generate| +|» temperature|body|number|false|The sampling temperature| + +> Example responses + +> 200 Response + +```json +{ + "id": "string", + "created": "string", + "model_name": "string", + "choices": [ + { + "role": "string", + "content": "string" + } + ] +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The output of the completion|[OpenAIChatCompletion](#schemaopenaichatcompletion)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +

validate

+ +## validate + + + +`POST /guards/{guardName}/validate` + +*Runs the validations specified in a Guard* + +> Body parameter + +```json +{ + "llmOutput": "stubbed llm output", + "numReasks": 0, + "promptParams": { + "property1": null, + "property2": null + }, + "llmApi": "openai.Completion.create", + "property1": null, + "property2": null +} +``` + +

Parameters

+ +|Name|In|Type|Required|Description| +|---|---|---|---|---| +|guardName|path|string|true|Guard name| +|x-openai-api-key|header|string(password)|false|A valid OpenAI API Key for calling LLM's on your behalf| +|body|body|[ValidatePayload](#schemavalidatepayload)|true|none| +|» **additionalProperties**|body|any|false|none| +|» llmOutput|body|string|false|The LLM output as a string or the input prompts for the LLM| +|» numReasks|body|integer|false|An override for the number of re-asks to perform| +|» promptParams|body|object|false|additional params for llm prompts| +|»» **additionalProperties**|body|any|false|none| +|» llmApi|body|[LLMResource](#schemallmresource)|false|none| + +#### Enumerated Values + +|Parameter|Value| +|---|---| +|» llmApi|openai.Completion.create| +|» llmApi|openai.completions.create| +|» llmApi|openai.ChatCompletion.create| +|» llmApi|openai.chat.completions.create| +|» llmApi|openai.Completion.acreate| +|» llmApi|openai.ChatCompletion.acreate| +|» llmApi|litellm.completion| +|» llmApi|litellm.acompletion| + +> Example responses + +> 200 Response + +```json +{ + "callId": "string", + "rawLlmOutput": "string", + "validatedOutput": "string", + "reask": { + "incorrectValue": true, + "failResults": [ + { + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + } + ], + "property1": null, + "property2": null + }, + "validationPassed": true, + "error": "string" +} +``` + +

Responses

+ +|Status|Meaning|Description|Schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|The output of the validation|[validation-outcome](#schemavalidation-outcome)| +|default|Default|Unexpected error|[HttpError](#schemahttperror)| + + + +## Schemas + +### OpenAIChatCompletionPayload + + + + + + +```json +{ + "model": "gpt-3.5-turbo", + "messages": [ + { + "role": "string", + "content": "string" + } + ], + "max_tokens": 0, + "temperature": 0 +} + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|model|string|false|none|The model to use for the completion| +|messages|[object]|false|none|The messages to use for the completion| +|» role|string|false|none|The role of the message| +|» content|string|false|none|The content of the message| +|max_tokens|integer|false|none|The maximum number of tokens to generate| +|temperature|number|false|none|The sampling temperature|= + +### OpenAIChatCompletion + + + + + + +```json +{ + "id": "string", + "created": "string", + "model_name": "string", + "choices": [ + { + "role": "string", + "content": "string" + } + ] +} + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|id|string|true|none|The id| +|created|string|true|none|The created date| +|model_name|string|true|none|The model name| +|choices|[object]|true|none|none| +|» role|string|false|none|The role of the message| +|» content|string|false|none|The content of the message| + +### HttpError + + + + + + +```json +{ + "status": 0, + "message": "string", + "cause": "string", + "fields": { + "property1": [ + "string" + ], + "property2": [ + "string" + ] + }, + "context": "string" +} + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|status|integer|true|none|A valid http status code| +|message|string|true|none|A message explaining the status| +|cause|string|false|none|Used to describe the origin of an error if that original error has meaning to the client. This field should add specificity to 'message'.| +|fields|object|false|none|Used to identify specific fields in a JSON body that caused the error. Typically only used for 4xx type responses. The key should be the json path to the invalid property and the value should be a list of error messages specific to that property.| +|» **additionalProperties**|[string]|false|none|none| +|context|string|false|none|Used to identify what part of the request caused the error for non-JSON payloads.| + +### HealthCheck + + + + + + +```json +{ + "status": 0, + "message": "string" +} + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|status|integer|true|none|A valid http status code| +|message|string|true|none|A message explaining the status| + +### ValidationOutcome + + + + + + +```json +{ + "callId": "string", + "rawLlmOutput": "string", + "validatedOutput": "string", + "reask": { + "incorrectValue": true, + "failResults": [ + { + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + } + ], + "property1": null, + "property2": null + }, + "validationPassed": true, + "error": "string" +} + +``` + +#### Properties + +*None* + +### primitives + + + + + + +```json +true + +``` + +#### Properties + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|boolean|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|integer|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|null|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|number|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|string|false|none|none| + +### objects + + + + + + +```json +{ + "property1": null, + "property2": null +} + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|**additionalProperties**|any|false|none|none| + +### arrays + + + + + + +```json +[ + true +] + +``` + +#### Properties + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[primitives](#schemaprimitives)|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[objects](#schemaobjects)|false|none|none| + +### any-type + + + + + + +```json +true + +``` + +AnyType + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|AnyType|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[primitives](#schemaprimitives)|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[objects](#schemaobjects)|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[arrays](#schemaarrays)|false|none|none| + +### validation-result + + + + + + +```json +{ + "outcome": "pass", + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true +} + +``` + +ValidationResult + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|outcome|string|true|none|none| +|metadata|object|false|none|none| +|» **additionalProperties**|any|false|none|none| +|validatedChunk|[any-type](#schemaany-type)|false|none|none| + +#### Enumerated Values + +|Property|Value| +|---|---| +|outcome|pass| +|outcome|fail| + +### error-span + + + + + + +```json +{ + "start": 0, + "end": 0, + "reason": "string" +} + +``` + +ErrorSpan + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|start|integer|true|none|none| +|end|integer|true|none|none| +|reason|string|true|none|The reason validation failed, specific to this chunk.| + +### fail-result + + + + + + +```json +{ + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true +} + +``` + +FailResult + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|FailResult|[validation-result](#schemavalidation-result)|false|none|The output from a single Validator.| +|outcome|any|true|none|none| +|errorMessage|string|true|none|none| +|fixValue|[any-type](#schemaany-type)|false|none|none| +|errorSpans|[[error-span](#schemaerror-span)]|false|none|none| + +### reask + + + + + + +```json +{ + "incorrectValue": true, + "failResults": [ + { + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + } + ], + "property1": null, + "property2": null +} + +``` + +ReAsk + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|**additionalProperties**|any|false|none|none| +|incorrectValue|[any-type](#schemaany-type)|false|none|none| +|failResults|[[fail-result](#schemafail-result)]|false|none|none| + +### validation-outcome + + + + + + +```json +{ + "callId": "string", + "rawLlmOutput": "string", + "validatedOutput": "string", + "reask": { + "incorrectValue": true, + "failResults": [ + { + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + } + ], + "property1": null, + "property2": null + }, + "validationPassed": true, + "error": "string" +} + +``` + +ValidationOutcome + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|callId|string|true|none|Foreign key to the most recent Call this resulted from.| +|rawLlmOutput|string|false|none|The raw, unchanged string content from the LLM call.| +|validatedOutput|any|false|none|The validated, and potentially fixed, output from the LLM call after undergoing validation.| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|object|false|none|none| +|»» **additionalProperties**|any|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[[any-type](#schemaany-type)]|false|none|none| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|reask|[reask](#schemareask)|false|none|If validation continuously fails and all allocated reasks are used, this field will contain the final reask that would have been sent to the LLM if additional reasks were available.| +|validationPassed|boolean|false|none|A boolean to indicate whether or not the LLM output passed validation. If this is False, the validated_output may be invalid.| +|error|string|false|none|If the validation process raised a handleable exception, this field will contain the error message.| + +### Guard + + + + + + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] +} + +``` + +#### Properties + +*None* + +### schemaArray + + + + + + +```json +[ + null +] + +``` + +#### Properties + +*None* + +### nonNegativeInteger + + + + + + +```json +0 + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|integer|false|none|none| + +### nonNegativeIntegerDefault0 + + + + + + +```json +0 + +``` + +#### Properties + +*None* + +### simpleTypes + + + + + + +```json +"array" + +``` + +#### Properties + +*None* + +### stringArray + + + + + + +```json +[] + +``` + +#### Properties + +*None* + +### LLMResponse + + + + + + +```json +{ + "promptTokenCount": 0, + "responseTokenCount": 0, + "output": "string", + "streamOutput": [ + "string" + ], + "asyncStreamOutput": [ + "string" + ] +} + +``` + +Information from the LLM response. + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|promptTokenCount|integer|false|none|none| +|responseTokenCount|integer|false|none|none| +|output|string|true|none|none| +|streamOutput|[string]|false|none|none| +|asyncStreamOutput|[string]|false|none|none| + +### CallInputs + + + + + + +```json +{ + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } +} + +``` + +CallInputs + +#### Properties + +allOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[inputs](#schemainputs)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[args-and-kwargs](#schemaargs-and-kwargs)|false|none|none| + +### ValidatorReference + + + + + + +```json +{ + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } +} + +``` + +ValidatorReference + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|ValidatorReference|[args-and-kwargs](#schemaargs-and-kwargs)|false|none|none| +|id|string|true|none|The unique identifier for this Validator. Often the hub id; e.g. guardrails/regex_match| +|on|any|false|none|A reference to the property this validator should be applied against. Can be a valid JSON path or a meta-property such as "prompt" or "output"| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|meta-property| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|JSON path to property; e.g. $.foo.bar| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|onFail|string|false|none|none| + +#### Enumerated Values + +|Property|Value| +|---|---| +|*anonymous*|prompt| +|*anonymous*|instructions| +|*anonymous*|msg_history| +|*anonymous*|messages| +|*anonymous*|output| +|onFail|exception| +|onFail|filter| +|onFail|fix| +|onFail|fix_reask| +|onFail|noop| +|onFail|reask| +|onFail|refrain| +|onFail|custom| + +### args-and-kwargs + + + + + + +```json +{ + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } +} + +``` + +ArgsAndKwargs + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|args|[[any-type](#schemaany-type)]|false|none|none| +|kwargs|object|false|none|none| +|» **additionalProperties**|any|false|none|none| + +### core + + + + + + +```json +{ + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {} +} + +``` + +Core vocabulary meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Core vocabulary meta-schema|object,boolean|false|none|none| +|$anchor|string|false|none|none| +|$ref|string(uri-reference)|false|none|none| +|$dynamicRef|string(uri-reference)|false|none|none| +|$dynamicAnchor|string|false|none|none| +|$vocabulary|object|false|none|none| +|» **additionalProperties**|boolean|false|none|none| +|$comment|string|false|none|none| +|$defs|object|false|none|none| +|» **additionalProperties**|any|false|none|none| + +### applicator + + + + + + +```json +{ + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null +} + +``` + +Applicator vocabulary meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Applicator vocabulary meta-schema|object,boolean|false|none|none| +|prefixItems|[schemaArray](#schemaschemaarray)|false|none|none| +|items|any|false|none|none| +|contains|any|false|none|none| +|additionalProperties|any|false|none|none| +|properties|object|false|none|none| +|» **additionalProperties**|any|false|none|none| +|patternProperties|object|false|none|none| +|» **additionalProperties**|any|false|none|none| +|dependentSchemas|object|false|none|none| +|» **additionalProperties**|any|false|none|none| +|propertyNames|any|false|none|none| +|if|any|false|none|none| +|then|any|false|none|none| +|else|any|false|none|none| +|allOf|[schemaArray](#schemaschemaarray)|false|none|none| +|anyOf|[schemaArray](#schemaschemaarray)|false|none|none| +|oneOf|[schemaArray](#schemaschemaarray)|false|none|none| +|not|any|false|none|none| + +### unevaluated + + + + + + +```json +{ + "unevaluatedItems": null, + "unevaluatedProperties": null +} + +``` + +Unevaluated applicator vocabulary meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Unevaluated applicator vocabulary meta-schema|object,boolean|false|none|none| +|unevaluatedItems|any|false|none|none| +|unevaluatedProperties|any|false|none|none| + +### validation + + + + + + +```json +{ + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array" +} + +``` + +Validation vocabulary meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Validation vocabulary meta-schema|object,boolean|false|none|none| +|multipleOf|number|false|none|none| +|maximum|number|false|none|none| +|exclusiveMaximum|number|false|none|none| +|minimum|number|false|none|none| +|exclusiveMinimum|number|false|none|none| +|maxLength|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|minLength|[nonNegativeIntegerDefault0](#schemanonnegativeintegerdefault0)|false|none|none| +|pattern|string(regex)|false|none|none| +|maxItems|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|minItems|[nonNegativeIntegerDefault0](#schemanonnegativeintegerdefault0)|false|none|none| +|uniqueItems|boolean|false|none|none| +|maxContains|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|minContains|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|maxProperties|[nonNegativeInteger](#schemanonnegativeinteger)|false|none|none| +|minProperties|[nonNegativeIntegerDefault0](#schemanonnegativeintegerdefault0)|false|none|none| +|required|[stringArray](#schemastringarray)|false|none|none| +|dependentRequired|object|false|none|none| +|» **additionalProperties**|[stringArray](#schemastringarray)|false|none|none| +|const|any|false|none|none| +|enum|[any]|false|none|none| +|type|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[simpleTypes](#schemasimpletypes)|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[[simpleTypes](#schemasimpletypes)]|false|none|none| + +#### meta-data + + + + + + +```json +{ + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ] +} + +``` + +Meta-data vocabulary meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Meta-data vocabulary meta-schema|object,boolean|false|none|none| +|title|string|false|none|none| +|description|string|false|none|none| +|default|any|false|none|none| +|deprecated|boolean|false|none|none| +|readOnly|boolean|false|none|none| +|writeOnly|boolean|false|none|none| +|examples|[any]|false|none|none| + +### format-annotation + + + + + + +```json +{ + "format": "string" +} + +``` + +Format vocabulary meta-schema for annotation results + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Format vocabulary meta-schema for annotation results|object,boolean|false|none|none| +|format|string|false|none|none| + +### content + + + + + + +```json +{ + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null +} + +``` + +Content vocabulary meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Content vocabulary meta-schema|object,boolean|false|none|none| +|contentMediaType|string|false|none|none| +|contentEncoding|string|false|none|none| +|contentSchema|any|false|none|none| + +### schema + + + + + + +```json +{ + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null +} + +``` + +Core and Validation specifications meta-schema + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|Core and Validation specifications meta-schema|object,boolean|false|none|none| +|definitions|object|false|none|none| +|» **additionalProperties**|any|false|none|none| +|dependencies|object|false|none|none| +|» **additionalProperties**|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»» *anonymous*|any|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|»» *anonymous*|[validation/definitions/stringArray](#schemavalidation/definitions/stringarray)|false|none|none| + +allOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[core](#schemacore)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[applicator](#schemaapplicator)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[unevaluated](#schemaunevaluated)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[validation](#schemavalidation)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[meta-data](#schemameta-data)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[format-annotation](#schemaformat-annotation)|false|none|none| + +and + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|[content](#schemacontent)|false|none|none| + +### inputs + + + + + + +```json +{ + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true +} + +``` + +Inputs + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|llmApi|string|false|none|The LLM resource targeted by the user. e.g. openai.chat.completions.create| +|llmOutput|string|false|none|The string output from an external LLM call provided by the user via Guard.parse.| +|instructions|string|false|none|The instructions for chat models.| +|prompt|string|false|none|The prompt for the LLM.| +|msgHistory|[object]|false|none|The message history for chat models.| +|» **additionalProperties**|any|false|none|none| +|promptParams|object|false|none|Parameters to be formatted into the prompt.| +|» **additionalProperties**|any|false|none|none| +|numReasks|integer|false|none|The total number of times the LLM can be called to correct output excluding the initial call.| +|metadata|object|false|none|Additional data to be used by Validators during execution time.| +|» **additionalProperties**|any|false|none|none| +|fullSchemaReask|boolean|false|none|Whether to perform reasks for the entire schema rather than for individual fields.| +|stream|boolean|false|none|Whether to use streaming.| + +### pass-result + + + + + + +```json +{ + "outcome": "pass", + "valueOverride": true, + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true +} + +``` + +PassResult + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|PassResult|[validation-result](#schemavalidation-result)|false|none|The output from a single Validator.| +|outcome|any|true|none|none| +|valueOverride|[any-type](#schemaany-type)|false|none|none| + +#### validator-log + + + + + + +```json +{ + "validatorName": "string", + "registeredName": "string", + "instanceId": "string", + "propertyPath": "string", + "valueBeforeValidation": true, + "valueAfterValidation": true, + "validationResult": { + "outcome": "pass", + "valueOverride": true, + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + }, + "startTime": "2019-08-24T14:15:22Z", + "endTime": "2019-08-24T14:15:22Z" +} + +``` + +ValidatorLog + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|validatorName|string(PascalCase)|true|none|The class name of the validator.| +|registeredName|string(kebab-case)|true|none|The registry id of the validator.| +|instanceId|any|false|none|A unique identifier for the validator that produced this log within the session.| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|integer|false|none|none| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|propertyPath|string|true|none|The JSON path to the property which was validated that produced this log.| +|valueBeforeValidation|[any-type](#schemaany-type)|true|none|none| +|valueAfterValidation|[any-type](#schemaany-type)|false|none|none| +|validationResult|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[pass-result](#schemapass-result)|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[fail-result](#schemafail-result)|false|none|none| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|startTime|string(date-time)|false|none|none| +|endTime|string(date-time)|false|none|none| + +### outputs + + + + + + +```json +{ + "llmResponseInfo": { + "promptTokenCount": 0, + "responseTokenCount": 0, + "output": "string", + "streamOutput": [ + "string" + ], + "asyncStreamOutput": [ + "string" + ] + }, + "rawOutput": "string", + "parsedOutput": "string", + "validationResponse": "string", + "guardedOutput": "string", + "reasks": [ + { + "incorrectValue": true, + "failResults": [ + { + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + } + ], + "property1": null, + "property2": null + } + ], + "validatorLogs": [ + { + "validatorName": "string", + "registeredName": "string", + "instanceId": "string", + "propertyPath": "string", + "valueBeforeValidation": true, + "valueAfterValidation": true, + "validationResult": { + "outcome": "pass", + "valueOverride": true, + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + }, + "startTime": "2019-08-24T14:15:22Z", + "endTime": "2019-08-24T14:15:22Z" + } + ], + "error": "string" +} + +``` + +Outputs + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|llmResponseInfo|[LLMResponse](#schemallmresponse)|false|none|Information from the LLM response.| +|rawOutput|string|false|none|The string content from the LLM response.| +|parsedOutput|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|object|false|none|none| +|»» **additionalProperties**|any|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[[any-type](#schemaany-type)]|false|none|none| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|validationResponse|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[reask](#schemareask)|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|object|false|none|none| +|»» **additionalProperties**|any|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[[any-type](#schemaany-type)]|false|none|none| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|guardedOutput|any|false|none|none| + +anyOf + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|string|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|object|false|none|none| +|»» **additionalProperties**|any|false|none|none| + +or + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|» *anonymous*|[[any-type](#schemaany-type)]|false|none|none| + +continued + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|reasks|[[reask](#schemareask)]|false|none|none| +|validatorLogs|[[validator-log](#schemavalidator-log)]|false|none|none| +|error|string|false|none|The error message from any exception which interrupted the Guard execution process.| + +### iteration + + + + + + +```json +{ + "id": "string", + "index": 0, + "callId": "string", + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true + }, + "outputs": { + "llmResponseInfo": { + "promptTokenCount": 0, + "responseTokenCount": 0, + "output": "string", + "streamOutput": [ + "string" + ], + "asyncStreamOutput": [ + "string" + ] + }, + "rawOutput": "string", + "parsedOutput": "string", + "validationResponse": "string", + "guardedOutput": "string", + "reasks": [ + { + "incorrectValue": true, + "failResults": [ + { + "outcome": "pass", + "errorMessage": "string", + "fixValue": true, + "errorSpans": [ + { + "start": 0, + "end": 0, + "reason": "string" + } + ], + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + } + ], + "property1": null, + "property2": null + } + ], + "validatorLogs": [ + { + "validatorName": "string", + "registeredName": "string", + "instanceId": "string", + "propertyPath": "string", + "valueBeforeValidation": true, + "valueAfterValidation": true, + "validationResult": { + "outcome": "pass", + "valueOverride": true, + "metadata": { + "property1": null, + "property2": null + }, + "validatedChunk": true + }, + "startTime": "2019-08-24T14:15:22Z", + "endTime": "2019-08-24T14:15:22Z" + } + ], + "error": "string" + } +} + +``` + +Iteration + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|id|string|true|none|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|index|integer|true|none|The zero-based index of this iteration within the current Call.| +|callId|string|true|none|The unique identifier for the Call that this iteration is a part of.| +|inputs|[inputs](#schemainputs)|false|none|none| +|outputs|[outputs](#schemaoutputs)|false|none|none| + +### call + + + + + + +```json +{ + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" +} + +``` + +Call + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|id|string|true|none|The unique identifier for this Call. Can be used as an identifier for a specific execution of a Guard.| +|iterations|[[iteration](#schemaiteration)]|false|none|none| +|inputs|[CallInputs](#schemacallinputs)|false|none|none| +|exception|string|false|none|none| + +### guard + + + + + + +```json +{ + "id": "string", + "name": "string", + "description": "string", + "validators": [ + { + "id": "string", + "on": "prompt", + "onFail": "exception", + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + } + ], + "output_schema": { + "definitions": {}, + "dependencies": { + "property1": {}, + "property2": {} + }, + "$anchor": "string", + "$ref": "../dictionary", + "$dynamicRef": "../dictionary", + "$dynamicAnchor": "string", + "$vocabulary": { + "property1": true, + "property2": true + }, + "$comment": "string", + "$defs": {}, + "prefixItems": [ + null + ], + "items": null, + "contains": null, + "additionalProperties": null, + "properties": {}, + "patternProperties": {}, + "dependentSchemas": { + "property1": null, + "property2": null + }, + "propertyNames": null, + "if": null, + "then": null, + "else": null, + "allOf": [ + null + ], + "anyOf": [ + null + ], + "oneOf": [ + null + ], + "not": null, + "unevaluatedItems": null, + "unevaluatedProperties": null, + "multipleOf": 0, + "maximum": 0, + "exclusiveMaximum": 0, + "minimum": 0, + "exclusiveMinimum": 0, + "maxLength": 0, + "minLength": 0, + "pattern": "/regex/", + "maxItems": 0, + "minItems": 0, + "uniqueItems": false, + "maxContains": 0, + "minContains": 0, + "maxProperties": 0, + "minProperties": 0, + "required": [], + "dependentRequired": { + "property1": [], + "property2": [] + }, + "const": null, + "enum": [ + null + ], + "type": "array", + "title": "string", + "description": "string", + "default": null, + "deprecated": false, + "readOnly": false, + "writeOnly": false, + "examples": [ + null + ], + "format": "string", + "contentMediaType": "string", + "contentEncoding": "string", + "contentSchema": null + }, + "history": [ + { + "id": "string", + "iterations": [], + "inputs": { + "llmApi": "string", + "llmOutput": "string", + "instructions": "string", + "prompt": "string", + "msgHistory": [ + { + "property1": null, + "property2": null + } + ], + "promptParams": { + "property1": null, + "property2": null + }, + "numReasks": 0, + "metadata": { + "property1": null, + "property2": null + }, + "fullSchemaReask": true, + "stream": true, + "args": [ + true + ], + "kwargs": { + "property1": null, + "property2": null + } + }, + "exception": "string" + } + ] +} + +``` + +Guard + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|id|string(kebab-case)|true|none|The unique identifier for the Guard.| +|name|string|true|none|The name for the Guard.| +|description|string|false|none|A description that concisely states the expected behaviour or purpose of the Guard.| +|validators|[[ValidatorReference](#schemavalidatorreference)]|false|none|none| +|output_schema|[schema](#schemaschema)|false|none|none| +|history|[[call](#schemacall)]|false|read-only|none| + +### ValidatePayload + + + + + + +```json +{ + "llmOutput": "stubbed llm output", + "numReasks": 0, + "promptParams": { + "property1": null, + "property2": null + }, + "llmApi": "openai.Completion.create", + "property1": null, + "property2": null +} + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|**additionalProperties**|any|false|none|none| +|llmOutput|string|false|none|The LLM output as a string or the input prompts for the LLM| +|numReasks|integer|false|none|An override for the number of re-asks to perform| +|promptParams|object|false|none|additional params for llm prompts| +|» **additionalProperties**|any|false|none|none| +|llmApi|[LLMResource](#schemallmresource)|false|none|none| + +### LLMResource + + + + + + +```json +"openai.Completion.create" + +``` + +#### Properties + +|Name|Type|Required|Restrictions|Description| +|---|---|---|---|---| +|*anonymous*|string|false|none|none| + +#### Enumerated Values + +|Property|Value| +|---|---| +|*anonymous*|openai.Completion.create| +|*anonymous*|openai.completions.create| +|*anonymous*|openai.ChatCompletion.create| +|*anonymous*|openai.chat.completions.create| +|*anonymous*|openai.Completion.acreate| +|*anonymous*|openai.ChatCompletion.acreate| +|*anonymous*|litellm.completion| +|*anonymous*|litellm.acompletion| diff --git a/docs/how_to_guides/custom_validator.ipynb b/docs/how_to_guides/custom_validator.ipynb new file mode 100644 index 000000000..7837dde3b --- /dev/null +++ b/docs/how_to_guides/custom_validator.ipynb @@ -0,0 +1,503 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create Custom Validators\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To make the implementation of custom validators easier, we have provided [an interface in the OSS](https://github.com/guardrails-ai/guardrails/blob/main/guardrails/validator_base.py).\n", + "\n", + "There are a few key steps to get up and running with a custom validator:\n", + "\n", + "1. Implementing the validator\n", + "2. Conforming to the required interface\n", + "3. Running Locally/Submitting to the Validator Hub\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, let's build out a simple custom validator. This validator will check if all text in the input is lowercase.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Any, Dict\n", + "import requests\n", + "from guardrails.validator_base import (\n", + " FailResult,\n", + " PassResult,\n", + " ValidationResult,\n", + " Validator,\n", + " register_validator,\n", + " ErrorSpan,\n", + ")\n", + "from typing import Optional, Callable\n", + "from rich import print\n", + "\n", + "\n", + "@register_validator(name=\"guardrails/lower_case\", data_type=\"string\")\n", + "class LowercaseValidator(Validator):\n", + " def __init__(\n", + " self,\n", + " on_fail: Optional[Callable] = None,\n", + " **kwargs,\n", + " ):\n", + " super().__init__(on_fail=on_fail, **kwargs)\n", + " self.rail_alias = \"lowercase\"\n", + "\n", + " def _validate(self, value: Any, metadata: Dict[str, Any]) -> ValidationResult:\n", + " if not isinstance(value, str):\n", + " return FailResult(\n", + " metadata=metadata,\n", + " error_message=\"Input must be a string.\",\n", + " fix_value=None,\n", + " )\n", + "\n", + " inference_result = self._inference(value)\n", + "\n", + " if inference_result:\n", + " return PassResult()\n", + " else:\n", + " return FailResult(\n", + " metadata=metadata,\n", + " error_message=\"Input must be lowercase.\",\n", + " fix_value=value.lower(),\n", + " )\n", + "\n", + " def _inference_local(self, model_input: str) -> bool:\n", + " \"\"\"Implement a function to perform inference on a local machine.\"\"\"\n", + " return model_input.islower()\n", + "\n", + " def _inference_remote(self, model_input: str) -> bool:\n", + " \"\"\"Implement a function that will build a request and perform inference on a\n", + " remote machine. This is not required if you will always use local mode.\n", + " \"\"\"\n", + " response = requests.post(self.validation_endpoint, json={\"inputs\": model_input})\n", + " if response.status_code != 200:\n", + " raise Exception(\n", + " f\"Remote inference failed with status code {response.status_code}\"\n", + " )\n", + "\n", + " return response.json().get(\"is_lowercase\", False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Simple usage running locally\n", + "\n", + "If this validator was stored locally in your codebase, you would want to import it\n", + "\n", + "```bash\n", + "from lowercase_validator import LowercaseValidator\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
PassResult(\n",
+       "    outcome='pass',\n",
+       "    value_override=<class 'guardrails.classes.validation.validation_result.PassResult.ValueOverrideSentinel'>,\n",
+       "    metadata=None,\n",
+       "    validated_chunk=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mPassResult\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33moutcome\u001b[0m=\u001b[32m'pass'\u001b[0m,\n", + " \u001b[33mvalue_override\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'guardrails.classes.validation.validation_result.PassResult.ValueOverrideSentinel'\u001b[0m\u001b[1m>\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidated_chunk\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
FailResult(\n",
+       "    outcome='fail',\n",
+       "    error_message='Input must be lowercase.',\n",
+       "    fix_value='hello world',\n",
+       "    error_spans=None,\n",
+       "    metadata={},\n",
+       "    validated_chunk=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mFailResult\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33moutcome\u001b[0m=\u001b[32m'fail'\u001b[0m,\n", + " \u001b[33merror_message\u001b[0m=\u001b[32m'Input must be lowercase.'\u001b[0m,\n", + " \u001b[33mfix_value\u001b[0m=\u001b[32m'hello world'\u001b[0m,\n", + " \u001b[33merror_spans\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mvalidated_chunk\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
FailResult(\n",
+       "    outcome='fail',\n",
+       "    error_message='Input must be lowercase.',\n",
+       "    fix_value='123',\n",
+       "    error_spans=None,\n",
+       "    metadata={},\n",
+       "    validated_chunk=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mFailResult\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33moutcome\u001b[0m=\u001b[32m'fail'\u001b[0m,\n", + " \u001b[33merror_message\u001b[0m=\u001b[32m'Input must be lowercase.'\u001b[0m,\n", + " \u001b[33mfix_value\u001b[0m=\u001b[32m'123'\u001b[0m,\n", + " \u001b[33merror_spans\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mvalidated_chunk\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
FailResult(\n",
+       "    outcome='fail',\n",
+       "    error_message='Input must be a string.',\n",
+       "    fix_value=None,\n",
+       "    error_spans=None,\n",
+       "    metadata={},\n",
+       "    validated_chunk=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mFailResult\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33moutcome\u001b[0m=\u001b[32m'fail'\u001b[0m,\n", + " \u001b[33merror_message\u001b[0m=\u001b[32m'Input must be a string.'\u001b[0m,\n", + " \u001b[33mfix_value\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33merror_spans\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[33mvalidated_chunk\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Usage example:\n", + "lowercase_validator = LowercaseValidator(use_local=True)\n", + "\n", + "\n", + "# Test cases for local validator\n", + "print(lowercase_validator.validate(value=\"hello world\", metadata={})) # PassResult\n", + "print(lowercase_validator.validate(\"Hello World\", {})) # FailResult\n", + "print(\n", + " lowercase_validator.validate(\"123\", {})\n", + ") # PassResult (numbers are considered lowercase)\n", + "print(lowercase_validator.validate(123, {})) # FailResult (not a string)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The best practice would be to use the validator in a Guardrails.Guard()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Make some imports\n", + "from rich import print\n", + "import guardrails as gd\n", + "import litellm\n", + "from IPython.display import clear_output\n", + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "prompt = \"\"\"Tell me a short snippet about the company Apple.\n", + "Make sure the output is all in lowercase. Don't use any capital letters.\"\"\"\n", + "\n", + "guard = gd.Guard().use(LowercaseValidator, use_local=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Instantiate a guard object\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='12637511488',\n",
+       "    raw_llm_output=\"apple inc. is a multinational technology company headquartered in cupertino, california. it \n",
+       "designs, manufactures, and markets consumer electronics, software, and online services. some of its most well-known\n",
+       "products include the iphone, ipad, mac computers, apple watch, and apple tv. the company is also known for its \n",
+       "innovative software platforms like ios, macos, watchos, and tvos, as well as services such as the app store, apple \n",
+       "music, and icloud. founded in 1976 by steve jobs, steve wozniak, and ronald wayne, apple has grown to become one of\n",
+       "the world's most valuable and influential companies.\",\n",
+       "    validated_output=\"apple inc. is a multinational technology company headquartered in cupertino, california. it \n",
+       "designs, manufactures, and markets consumer electronics, software, and online services. some of its most well-known\n",
+       "products include the iphone, ipad, mac computers, apple watch, and apple tv. the company is also known for its \n",
+       "innovative software platforms like ios, macos, watchos, and tvos, as well as services such as the app store, apple \n",
+       "music, and icloud. founded in 1976 by steve jobs, steve wozniak, and ronald wayne, apple has grown to become one of\n",
+       "the world's most valuable and influential companies.\",\n",
+       "    reask=None,\n",
+       "    validation_passed=True,\n",
+       "    error=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'12637511488'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m\"apple\u001b[0m\u001b[32m inc. is a multinational technology company headquartered in cupertino, california. it \u001b[0m\n", + "\u001b[32mdesigns, manufactures, and markets consumer electronics, software, and online services. some of its most well-known\u001b[0m\n", + "\u001b[32mproducts include the iphone, ipad, mac computers, apple watch, and apple tv. the company is also known for its \u001b[0m\n", + "\u001b[32minnovative software platforms like ios, macos, watchos, and tvos, as well as services such as the app store, apple \u001b[0m\n", + "\u001b[32mmusic, and icloud. founded in 1976 by steve jobs, steve wozniak, and ronald wayne, apple has grown to become one of\u001b[0m\n", + "\u001b[32mthe world's most valuable and influential companies.\"\u001b[0m,\n", + " \u001b[33mvalidated_output\u001b[0m=\u001b[32m\"apple\u001b[0m\u001b[32m inc. is a multinational technology company headquartered in cupertino, california. it \u001b[0m\n", + "\u001b[32mdesigns, manufactures, and markets consumer electronics, software, and online services. some of its most well-known\u001b[0m\n", + "\u001b[32mproducts include the iphone, ipad, mac computers, apple watch, and apple tv. the company is also known for its \u001b[0m\n", + "\u001b[32minnovative software platforms like ios, macos, watchos, and tvos, as well as services such as the app store, apple \u001b[0m\n", + "\u001b[32mmusic, and icloud. founded in 1976 by steve jobs, steve wozniak, and ronald wayne, apple has grown to become one of\u001b[0m\n", + "\u001b[32mthe world's most valuable and influential companies.\"\u001b[0m,\n", + " \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidation_passed\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "result = fragment_generator = guard(\n", + " litellm.completion,\n", + " model=\"gpt-4o\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": prompt},\n", + " ],\n", + " max_tokens=1024,\n", + " temperature=0,\n", + ")\n", + "\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you would like an improved implementation, you can implement the new ErrorSpan feature. This class provides a way to define the span of the error in the input.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "@register_validator(name=\"guardrails/lower_case\", data_type=\"string\")\n", + "class LowercaseValidator(Validator):\n", + " def __init__(\n", + " self,\n", + " on_fail: Optional[Callable] = None,\n", + " **kwargs,\n", + " ):\n", + " super().__init__(on_fail=on_fail, **kwargs)\n", + " self.rail_alias = \"lowercase\"\n", + "\n", + " def _validate(self, value: Any, metadata: Dict[str, Any]) -> ValidationResult:\n", + " if not isinstance(value, str):\n", + " return FailResult(error_message=\"Input must be a string.\", fix_value=None)\n", + "\n", + " inference_result = self._inference(value)\n", + " error_spans = []\n", + " if inference_result:\n", + " for result in inference_result:\n", + " error_spans.append(\n", + " ErrorSpan(\n", + " start=result[0], end=result[1], reason=\"Input must be lowercase.\"\n", + " )\n", + " )\n", + " return FailResult(\n", + " error_message=\"Inputs must be lowercase.\",\n", + " fix_value=value.lower(),\n", + " error_spans=error_spans\n", + " )\n", + " return PassResult()\n", + "\n", + " def _inference_local(self, model_input: str) -> bool:\n", + " \"\"\"Implement a function to perform inference on a local machine.\"\"\"\n", + " error_spans = []\n", + " start = None\n", + "\n", + " for i, char in enumerate(model_input):\n", + " if char.isupper():\n", + " if start is None:\n", + " start = i\n", + " elif start is not None:\n", + " error_spans.append((start, i - 1))\n", + " start = None\n", + "\n", + " if start is not None:\n", + " error_spans.append((start, len(model_input) - 1))\n", + " return error_spans\n", + "\n", + " def _inference_remote(self, model_input: str) -> bool:\n", + " \"\"\"Implement a function that will build a request and perform inference on a\n", + " remote machine. This is not required if you will always use local mode.\n", + " \"\"\"\n", + " response = requests.post(self.validation_endpoint, json={\"inputs\": model_input})\n", + " if response.status_code != 200:\n", + " raise Exception(\n", + " f\"Remote inference failed with status code {response.status_code}\"\n", + " )\n", + "\n", + " return response.json().get(\"is_lowercase\", False)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='12637505888',\n",
+       "    raw_llm_output=\"APPLE INC. IS A MULTINATIONAL TECHNOLOGY COMPANY HEADQUARTERED IN CUPERTINO, CALIFORNIA. \n",
+       "FOUNDED BY STEVE JOBS, STEVE WOZNIAK, AND RONALD WAYNE IN 1976, APPLE IS RENOWNED FOR ITS INNOVATIVE PRODUCTS SUCH \n",
+       "AS THE IPHONE, IPAD, MAC COMPUTERS, APPLE WATCH, AND APPLE TV. THE COMPANY IS ALSO KNOWN FOR ITS SOFTWARE \n",
+       "ECOSYSTEM, INCLUDING IOS, MACOS, WATCHOS, AND SERVICES LIKE THE APP STORE, APPLE MUSIC, AND ICLOUD. APPLE IS ONE OF\n",
+       "THE WORLD'S MOST VALUABLE COMPANIES AND A LEADER IN THE TECHNOLOGY INDUSTRY.\",\n",
+       "    validated_output=\"APPLE INC. IS A MULTINATIONAL TECHNOLOGY COMPANY HEADQUARTERED IN CUPERTINO, CALIFORNIA. \n",
+       "FOUNDED BY STEVE JOBS, STEVE WOZNIAK, AND RONALD WAYNE IN 1976, APPLE IS RENOWNED FOR ITS INNOVATIVE PRODUCTS SUCH \n",
+       "AS THE IPHONE, IPAD, MAC COMPUTERS, APPLE WATCH, AND APPLE TV. THE COMPANY IS ALSO KNOWN FOR ITS SOFTWARE \n",
+       "ECOSYSTEM, INCLUDING IOS, MACOS, WATCHOS, AND SERVICES LIKE THE APP STORE, APPLE MUSIC, AND ICLOUD. APPLE IS ONE OF\n",
+       "THE WORLD'S MOST VALUABLE COMPANIES AND A LEADER IN THE TECHNOLOGY INDUSTRY.\",\n",
+       "    reask=None,\n",
+       "    validation_passed=False,\n",
+       "    error=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mValidationOutcome\u001b[0m\u001b[1m(\u001b[0m\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'12637505888'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m\"APPLE\u001b[0m\u001b[32m INC. IS A MULTINATIONAL TECHNOLOGY COMPANY HEADQUARTERED IN CUPERTINO, CALIFORNIA. \u001b[0m\n", + "\u001b[32mFOUNDED BY STEVE JOBS, STEVE WOZNIAK, AND RONALD WAYNE IN 1976, APPLE IS RENOWNED FOR ITS INNOVATIVE PRODUCTS SUCH \u001b[0m\n", + "\u001b[32mAS THE IPHONE, IPAD, MAC COMPUTERS, APPLE WATCH, AND APPLE TV. THE COMPANY IS ALSO KNOWN FOR ITS SOFTWARE \u001b[0m\n", + "\u001b[32mECOSYSTEM, INCLUDING IOS, MACOS, WATCHOS, AND SERVICES LIKE THE APP STORE, APPLE MUSIC, AND ICLOUD. APPLE IS ONE OF\u001b[0m\n", + "\u001b[32mTHE WORLD'S MOST VALUABLE COMPANIES AND A LEADER IN THE TECHNOLOGY INDUSTRY.\"\u001b[0m,\n", + " \u001b[33mvalidated_output\u001b[0m=\u001b[32m\"APPLE\u001b[0m\u001b[32m INC. IS A MULTINATIONAL TECHNOLOGY COMPANY HEADQUARTERED IN CUPERTINO, CALIFORNIA. \u001b[0m\n", + "\u001b[32mFOUNDED BY STEVE JOBS, STEVE WOZNIAK, AND RONALD WAYNE IN 1976, APPLE IS RENOWNED FOR ITS INNOVATIVE PRODUCTS SUCH \u001b[0m\n", + "\u001b[32mAS THE IPHONE, IPAD, MAC COMPUTERS, APPLE WATCH, AND APPLE TV. THE COMPANY IS ALSO KNOWN FOR ITS SOFTWARE \u001b[0m\n", + "\u001b[32mECOSYSTEM, INCLUDING IOS, MACOS, WATCHOS, AND SERVICES LIKE THE APP STORE, APPLE MUSIC, AND ICLOUD. APPLE IS ONE OF\u001b[0m\n", + "\u001b[32mTHE WORLD'S MOST VALUABLE COMPANIES AND A LEADER IN THE TECHNOLOGY INDUSTRY.\"\u001b[0m,\n", + " \u001b[33mreask\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + " \u001b[33mvalidation_passed\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + " \u001b[33merror\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "guard = gd.Guard().use(LowercaseValidator, use_local=True)\n", + "prompt = \"\"\"Tell me a short snippet about the company Apple. Make it all uppercase\"\"\"\n", + "\n", + "result = guard(\n", + " litellm.completion,\n", + " prompt=prompt,\n", + " model=\"gpt-4o\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": prompt},\n", + " ],\n", + " max_tokens=1024,\n", + " temperature=0,\n", + ")\n", + "print(result)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/how_to_guides/deploying_aws.md b/docs/how_to_guides/deploying_aws.md new file mode 100644 index 000000000..b40561fb5 --- /dev/null +++ b/docs/how_to_guides/deploying_aws.md @@ -0,0 +1,596 @@ +# AWS - Deploying Guardrails Server + +Guardrails allows you to deploy a dedicated server to run guard executions while continuing to use the Guardrails SDK as you do today. + +In this cookbook we show an example of deploying a containerized version of Guardrails API into AWS leveraging AWS ECS. + +> Note: Guardrails API is a feature is available as of `>=0.5.0` + + +# Step 1: Containerizing Guardrails API + +Create a `Dockerfile` in a new working directory `guardrails-server` (or alternative) + +```Dockerfile +FROM python:3.11-slim + +ARG GUARDRAILS_TOKEN +ARG GUARDRAILS_SDK_VERSION="guardrails-ai[api]>=0.5.0,<6" + +# Set environment variables to avoid writing .pyc files and to unbuffer Python output +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +ENV LOGLEVEL="DEBUG" +ENV GUARDRAILS_LOG_LEVEL="DEBUG" +ENV APP_ENVIRONMENT="production" + +WORKDIR /app + +# Install Git and necessary dependencies +RUN apt-get update && \ + apt-get install -y git curl gcc jq && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Install guardrails, the guardrails API, and gunicorn +RUN pip install $GUARDRAILS_SDK_VERSION "gunicorn" + +RUN guardrails configure --enable-metrics --enable-remote-inferencing --token $GUARDRAILS_TOKEN + +# Copy the hub requirements file to the container +COPY hub-requirements.txt /app/hub-requirements.txt + +# Install hub dependencies +RUN export GR_INSTALLS=$(python -c 'print(",".join(open("./hub-requirements.txt", encoding="utf-8").read().splitlines()))'); \ + set -e; IFS=','; \ + for url in $GR_INSTALLS; do \ + if [ -n "$url" ]; then \ + guardrails hub install --quiet --no-install-local-models "$url"; \ + fi; \ + done + +# Overwrite Config file with one with user's settings +COPY config.py /app/config.py + +# Copy the guardrails API config file to the installed package +RUN cp /app/config.py $(pip show guardrails-api | grep Location | awk '{print $2}')/guardrails_api/config.py + +# Expose port 8000 for the application +EXPOSE 8000 + +# Command to start the Gunicorn server with specified settings +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--timeout=5", "--threads=3", "guardrails_api.app:create_app()"] +``` + +Then create a `hub-requirements.txt` file containing all of the hub installs required for your Guards: + +*Example:* +``` +hub://guardrails/competitor_check +hub://guardrails/toxic_language +``` + +At this point you can now generate the required config file (`config.py`) which is needed for the server to know how to configure each guard. + +```bash +guardrails create --validators=$(python -c 'print(",".join(open("./hub-requirements.txt", encoding="utf-8").read().splitlines()))') +``` + +> ⚠️ *Important:* Ensure to add in any telemetry configuration and guard configuration to the config file AND ensure each guard is given a variable name i.e `guard1 = Guard(...)` + +# Step 2: Deploying Infra + +By leveraging AWS ECS we can scale to handle increasing workloads by scaling the number of containers. Furthermore we can leverage a streamlined deployment process using ECS with rolling updates (Step 3). + +We can now deploy the infrastructure needed for AWS ECS which includes: +- Networking Resources (VPC, Load Balancer, Security Groups, Subnets, ect) +- IAM Roles & Policies (ECS Task & Execution Role) +- ECS Cluster (ECS Service, Task, Task Definition) + +We start by initilizing terraform with: + +```bash +terraform init +``` + +One can then copy the provided [Terraform Code](#Terraform) or use their own by placing into our working directory and running: + +```bash +terraform apply -var="aws_region=us-east-1" -var="backend_memory=16384" -var="backend_cpu=8192" -var="desired_count=0" +``` + +> Each can be configured based on your requirements. `desired_count` corresponds to the number of containers that should always be running. Alternatively one can configure a minimum & maximum count with some autoscaling policy. It is initially set to `0` since we have yet to upload the container to the AWS container registry (ECR). + +Once the deployment has succeeded you should see some output values (which will be required if you wish to set up CI). + +# Step 3 + +You can deploy the application manually as specified in Step 3a or skip to Step 3b to deploy the application with CI. + +## Step 3a: Deploying Application Manually + +Firstly, create or use your existing guardrails token and export it to your current shell `export GUARDRAILS_TOKEN="..."` + +```bash +# Optionally use the command below to use your existing token +export GUARDRAILS_TOKEN=$(cat ~/.guardrailsrc| awk -F 'token=' '{print $2}' | awk '{print $1}' | tr -d '\n') +``` + +Run the following to build your container and push up to ECR: + +```bash +# Build Container +docker build --platform linux/amd64 --build-arg GUARDRAILS_TOKEN=$GUARDRAILS_TOKEN -t guardrails-api:latest . + +# Push to ECR +aws ecr get-login-password --region ${YOUR_AWS_REGION} | docker login --username AWS --password-stdin ${YOUR_AWS_ACCOUNT_ID}.dkr.ecr.${YOUR_AWS_REGION}.amazonaws.com +docker tag guardrails-api:latest ${YOUR_AWS_ACCOUNT_ID}.dkr.ecr.${YOUR_AWS_REGION}.amazonaws.com/gr-backend-images:latest +docker push ${YOUR_AWS_ACCOUNT_ID}.dkr.ecr.${YOUR_AWS_REGION}.amazonaws.com/gr-backend-images:latest +``` + +Lastly you can deploy your ECS service by scaling up the container count using the AWS CLI: + +```bash +aws ecs update-service --cluster gr-backend-ecs-cluster --service gr-backend-ecs-service --desired-count 3 --force-new-deployment +``` + + +## Step 3b: Deploying Application Using CI + +In some cases you may update your `config.py` file or your `hub-requirements.txt` file to add/remove guards. Here it may help to set up CI to automate the process of updating your Guardrails API container and deploy to ECS. + +For this to work you must set the following configuration on Github Actions: +- `AWS_ACCESS_KEY_ID` [Secret] +- `AWS_SECRET_ACCESS_KEY` [Secret] +- `AWS_ECR_REPOSITORY` [Variable] Can be set to the output of `terraform output -raw ecr_repository_url` +- `AWS_ECS_CLUSTER_NAME` [Variable] Can be set to `gr-backend-ecs-cluster` as default +- `AWS_ECS_SERVICE_NAME` [Variable] Can be set to `gr-backend-ecs-service` as default + +Here is some provided Github Actions workflow which does this on pushes to the `main` branch: + + +```yaml +name: Deploy Backend + +on: + push: + branches: + - main + +jobs: + deploy_app: + name: Deploy Backend + runs-on: ubuntu-latest + env: + AWS_REGION: us-east-1 + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_ECR_REPOSITORY: ${{ vars.AWS_ECR_REPOSITORY }} + AWS_ECS_CLUSTER_NAME: ${{ vars.AWS_ECS_CLUSTER_NAME }} + AWS_ECS_SERVICE_NAME: ${{ vars.AWS_ECS_SERVICE_NAME }} + WORKING_DIR: "./" + steps: + + - name: Check out head + uses: actions/checkout@v3 + with: + persist-credentials: false + + - name: Set up QEMU + uses: docker/setup-qemu-action@master + with: + platforms: linux/amd64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@master + with: + platforms: linux/amd64 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.AWS_REGION }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build & Push ECR Image + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ${{ env.WORKING_DIR }} + platforms: linux/amd64 + cache-from: type=gha + cache-to: type=gha,mode=max + push: true + tags: ${{ env.AWS_ECR_REPOSITORY }}:latest + + - name: Deploy to ECS + run: | + aws ecs update-service --cluster ${{ env.AWS_ECS_CLUSTER_NAME }} --service ${{ env.AWS_ECS_SERVICE_NAME }} --desired-count 1 --force-new-deployment + env: + AWS_DEFAULT_REGION: ${{ env.AWS_REGION }} + + +``` + +# Step 4: Using with SDK + +You should be able to get the URL for your Guardrails API using: + +```bash +export GUARDRAILS_BASE_URL=$(terraform output -raw backend_service_url) +echo "http://$GUARDRAILS_BASE_URL" +``` + +By setting the above environment variable `GUARDRAILS_BASE_URL` the SDK will be able to use this as a backend for running validations. + + +# Considerations for Production + +When building the container we made some crucial choices in order to make Guardrails production ready. Namely we opted for remote inferencing & did not include local models. This allows us to reduce the image size by preventing heavy validators from being included in the final container image and instead use hosted versions of ML based validators. + +In addition to the configuration above we recommend that you host your ECS cluster in private subnet and configure autoscaling policies with appropriate minimum & maximum container counts based on your expected workloads. Furthermore, we recommend that you also serve the API using HTTPs. + +Lastly, you can configure the below terraform code as you see fit including but not limited to: +- Turning into a terraform module by placing into a subfolder within your main terraform module +- Configuring default memory & cpu units per container +- Setting up autoscaling policies and Cloudwatch Alarms +- Setting up Telemetry with AWS X-Ray + +# Terraform + +```hcl +locals { + deployment_name = "gr-backend" +} + +variable "aws_region" { + description = "AWS region to deploy the resources" + type = string + default = "us-east-2" +} + +variable "backend_cpu" { + description = "CPU units for the service" + type = number + default = 1*1024 +} + +variable "backend_memory" { + description = "Memory units for the service" + type = number + default = 2*1024 +} + +variable "backend_server_port" { + description = "Port on which the backend server listens" + type = number + default = 8000 +} + +variable "desired_count" { + description = "Number of tasks to run" + type = number + default = 0 +} + +provider "aws" { + region = var.aws_region + + default_tags { + tags = { + Offering = "Guardrails Backend" + Vendor = "Guardrails" + Terraform = "True" + } + } +} + +################# Networking Resources + +data "aws_availability_zones" "available" {} + + +resource "aws_vpc" "backend" { + cidr_block = "10.0.0.0/16" + enable_dns_hostnames = true + + tags = { + Name = "${local.deployment_name}-vpc" + } +} + +resource "aws_subnet" "backend_public_subnets" { + count = 3 + vpc_id = aws_vpc.backend.id + cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] + map_public_ip_on_launch = true + + tags = { + Name = "${local.deployment_name}-public-subnet-${count.index}" + } +} + +resource "aws_eip" "backend" { + count = 2 + vpc = true + depends_on = [aws_internet_gateway.backend] +} + +resource "aws_nat_gateway" "backend" { + count = 2 + subnet_id = aws_subnet.backend_public_subnets[count.index].id + allocation_id = aws_eip.backend[count.index].id +} + +resource "aws_internet_gateway" "backend" { + vpc_id = aws_vpc.backend.id + + tags = { + Name = "${local.deployment_name}-igw" + } +} + +resource "aws_route_table" "backend_public_routes" { + vpc_id = aws_vpc.backend.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.backend.id + } +} + +resource "aws_route_table_association" "backend_public_routes" { + count = length(aws_subnet.backend_public_subnets) + subnet_id = aws_subnet.backend_public_subnets[count.index].id + route_table_id = aws_route_table.backend_public_routes.id +} + +resource "aws_lb" "app_lb" { + name = "${local.deployment_name}-nlb" + load_balancer_type = "network" + internal = false + subnets = aws_subnet.backend_public_subnets[*].id + enable_cross_zone_load_balancing = false +} + +resource "aws_lb_listener" "app_lb_listener" { + load_balancer_arn = aws_lb.app_lb.arn + + protocol = "TCP" + port = 80 + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.app_lb.arn + } +} + +resource "aws_lb_target_group" "app_lb" { + name = "${local.deployment_name}-nlb-tg" + protocol = "TCP" + port = 80 + vpc_id = aws_vpc.backend.id + target_type = "ip" + + health_check { + healthy_threshold = "2" + interval = "30" + protocol = "HTTP" + timeout = "3" + unhealthy_threshold = "3" + path = "/" + } + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group" "backend" { + name = "${local.deployment_name}-firewall" + description = "Guardrails backend firewall" + vpc_id = aws_vpc.backend.id + + ingress { + description = "Guardrails API Access" + from_port = var.backend_server_port + to_port = var.backend_server_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + description = "Allow all outbound traffic" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + revoke_rules_on_delete = true +} + +################# Log Resources + +resource "aws_cloudwatch_log_group" "backend_log_group" { + name = "${local.deployment_name}-log-group" + retention_in_days = 30 +} + +################# Application Resources + +resource "aws_ecr_repository" "backend_images" { + name = "${local.deployment_name}-images" +} + +resource "aws_ecs_cluster" "backend" { + name = "${local.deployment_name}-ecs-cluster" + + configuration { + execute_command_configuration { + logging = "OVERRIDE" + + log_configuration { + cloud_watch_encryption_enabled = false + cloud_watch_log_group_name = aws_cloudwatch_log_group.backend_log_group.name + } + } + } + + setting { + name = "containerInsights" + value = "enabled" + } +} + +data "aws_caller_identity" "current" {} + +resource "aws_ecs_task_definition" "backend" { + family = "${local.deployment_name}-backend-task-defn" + execution_role_arn = aws_iam_role.ecs_execution_role.arn + task_role_arn = aws_iam_role.ecs_task_role.arn + network_mode = "awsvpc" + requires_compatibilities = ["FARGATE"] + cpu = var.backend_cpu + memory = var.backend_memory + + container_definitions = jsonencode([ + { + name = "${local.deployment_name}-task", + image = "${aws_ecr_repository.backend_images.repository_url}:latest", + cpu = var.backend_cpu, + memory = var.backend_memory, + networkMode = "awsvpc", + + portMappings = [ + { + containerPort = var.backend_server_port, + hostPort = var.backend_server_port, + protocol = "tcp" + } + ], + logConfiguration = { + logDriver = "awslogs", + options = { + "awslogs-group" = aws_cloudwatch_log_group.backend_log_group.name, + "awslogs-region" = var.aws_region, + "awslogs-stream-prefix" = "backend" + } + }, + linuxParameters = { + initProcessEnabled = true + }, + healthCheck = { + command = ["CMD-SHELL", "curl -f http://localhost:${var.backend_server_port}/ || exit 1"], + interval = 30, + startPeriod = 30, + timeout = 10, + retries = 3 + }, + environment = [ + { + name = "AWS_ACCOUNT_ID", + value = data.aws_caller_identity.current.account_id + }, + { + name = "HOST", + value = "http://${aws_lb.app_lb.dns_name}" + }, + { + name = "SELF_ENDPOINT", + value = "http://${aws_lb.app_lb.dns_name}:${var.backend_server_port}" + } + ], + essential = true + } + ]) +} + + +resource "aws_ecs_service" "backend" { + name = "${local.deployment_name}-ecs-service" + cluster = aws_ecs_cluster.backend.id + task_definition = aws_ecs_task_definition.backend.arn + desired_count = var.desired_count + launch_type = "FARGATE" + + enable_execute_command = true + wait_for_steady_state = true + + network_configuration { + security_groups = [aws_security_group.backend.id] + subnets = aws_subnet.backend_public_subnets[*].id + assign_public_ip = true + } + + load_balancer { + target_group_arn = aws_lb_target_group.app_lb.id + container_name = "${local.deployment_name}-task" + container_port = var.backend_server_port + } + + lifecycle { + ignore_changes = [task_definition] + } + + deployment_circuit_breaker { + enable = true + rollback = true + } +} + +################# IAM Roles and Policies + +resource "aws_iam_role" "ecs_execution_role" { + name = "${local.deployment_name}-ecs-execution-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Principal = { + Service = "ecs-tasks.amazonaws.com" + } + Effect = "Allow" + }, + ] + }) +} + +resource "aws_iam_role_policy_attachment" "ecs_execution_role_policy" { + role = aws_iam_role.ecs_execution_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" +} + +resource "aws_iam_role" "ecs_task_role" { + name = "${local.deployment_name}-ecs-task-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Principal = { + Service = "ecs-tasks.amazonaws.com" + } + Effect = "Allow" + }, + ] + }) +} + +output "ecr_repository_url" { + value = aws_ecr_repository.backend_images.repository_url +} + +output "backend_service_url" { + value = aws_lb.app_lb.dns_name +} +``` \ No newline at end of file diff --git a/docs/how_to_guides/enable_streaming.md b/docs/how_to_guides/enable_streaming.md new file mode 100644 index 000000000..fff3729e1 --- /dev/null +++ b/docs/how_to_guides/enable_streaming.md @@ -0,0 +1,60 @@ +# Stream Validated Output + +To stream validated output, you need only pass the `stream=True` flag through the `guard` function. This will return a generator that will yield `GuardResult` objects as they are processed. + +```python +from guardrails import Guard +import os + +# Set your OpenAI API key +# os.environ['OPENAI_API_KEY'] = "" + +guard = Guard() + +stream_chunk_generator = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="gpt-3.5-turbo", + stream=True +) + +# Print the validated output as it is processed +for chunk in stream_chunk_generator: + print(f"{chunk.validated_output}") + +``` + +## Using Validators with Streaming + +Using validators with streaming works the same way. Note that not all `on_fail` types are supported with streaming. See the full list [here](../concepts/error_remediation). + +```bash +guardrails hub install hub://guardrails/profanity_free +``` + +```python +from guardrails import Guard +from guardrails.hub import ProfanityFree +import os + +# Set your OpenAI API key +# os.environ['OPENAI_API_KEY'] = "" + +guard = Guard().use(ProfanityFree()) + +stream_chunk_generator = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="gpt-3.5-turbo", + stream=True +) + +# Print the validated output as it is processed +for chunk in stream_chunk_generator: + print(f"{chunk.validated_output}") +``` + +## Learn more +Read more about streaming in our concept docs: + +- [Streaming](../concepts/streaming) +- [Async Stream-validate LLM responses](../concepts/async_streaming) +- [Streaming Structured Data](../concepts/streaming_structured_data) \ No newline at end of file diff --git a/docs/how_to_guides/generate_structured_data.md b/docs/how_to_guides/generate_structured_data.md new file mode 100644 index 000000000..ccbd5f3fe --- /dev/null +++ b/docs/how_to_guides/generate_structured_data.md @@ -0,0 +1,135 @@ +# Generate Structured Data + +Guardrails provides several interfaces to help llms respond in valid JSON which can then be validated using Guardrails validators. In this cookbook, we'll demonstrate how each interface is used with examples. + +To learn more about our approach to structured data, see the [Structured Data](https://guardrailsai.com/docs/structured_data) guide. + +## Prerequisites + +First, create a Pydantic model and guard for the structured data. The model should describe the data structure to be returned. Pydantic Fields support Guardrails validators and are initialized at the same time as validators. + +We've included here a sample prompt and data asking an LLM to produce some structured data. + +Learn more about pydantic [here](https://docs.pydantic.dev/latest/why/). + +```py +from guardrails import Guard +from guardrails.hub import RegexMatch +from pydantic import BaseModel, Field +from typing import List + +NAME_REGEX = "^[A-Z][a-z]+\s[A-Z][a-z]+$" + +class Delivery(BaseModel): + custome_name: str=Field(validators=[RegexMatch(regex=NAME_REGEX)], description="customer name") + pickup_time: str=Field(description="date and time of pickup") + pickup_location: str=Field(description="address of pickup") + dropoff_time: str=Field(description="date and time of dropoff") + dropoff_location: str=Field(description="address of dropoff") + price: str = Field(description="price of delivery with currency symbol included") + +class Schedule(BaseModel): + deliveries: List[Delivery] + +guard = Guard.from_pydantic(Schedule) +chat_history=""" +nelson and murdock: i need a pickup 797 9th Avenue, manila envelope, June 3 10:00am with dropoff 10:30am Courthouse, 61 Center Street C/O frank james +operator: quote - $23.00 +neslon and murdock: perfect, we accept the quote +operator: 797 9th ave, 10:00am pickup comfirmed +abc flowers: i need a pickup of a flowers from abc flowers at 21 3rd street at 11:00am on june 2 with a dropoff at 75th Ave at 5:30pm same day +operator: 21 3rd street flowers quote - $14.50 +abc flowers: accepted +polk and wardell: i need a pickup of a bagels from Bakers Co at 331 5th street at 11:00am on june 3 with a dropoff at 75th Ave at 5:30pm same day +operator: 331 5th street bagels quote - $34.50 +polk and wardell: accepted +""" + +prompt = """ +From the chat exchanges below extract a schedule of deliveries. +Chats: +${chat_history} +""" + +messages = [{ + "role": "system", + "content": "You are a helpful assistant." +}, { + "role": "user", + "content": prompt +}] +``` + +## Options + +### Function/tool calling structured response formatting + +For models that support openai tool/function calling(`gpt-4o`, `gpt-4-turbo`, or `gpt-3.5-turbo`). Learn more about tools [here](https://guardrailsai.com/docs/tools). + +```py +tools = [] # an open ai compatible list of tools + +response = guard( + model="gpt-4o", + messages=messages, + prompt_params={"chat_history": chat_history}, + tools=guard.json_function_calling_tool(tools), + tool_choice="required", +) +``` + +### Prompt Updates + +For models that support JSON through prompt engineering and hinting (most models). Learn more about prompt engineering for structured data [here](https://guardrailsai.com/docs/prompt_engineering). + + +```py +prompt+=""" + +${gr.complete_json_suffix_v3} +""" +response = guard( + model="gpt-4o", + messages=[messages[0],{ + "role": "user", + "content": prompt + }], + prompt_params={"chat_history": chat_history}, +) +``` + +### Constrained decoding structured response formatting + +For Hugging Face models structured JSON output maybe returned utilizing constrained decoding. Constrained decoding is a technique that allows you to guide the model to generate a specific type of output, a little bit like JSON ad-libs. Learn more about constrained decoding [here](https://guardrailsai.com/docs/constrained_decoding). + +```python +g = Guard.from_pydantic(NewFriends, output_formatter="jsonformer") + +# JSONFormer is only compatible with HF Pipelines and HF Models: +from transformers import pipeline +pipe = pipeline("text-generation", "TinyLlama/TinyLlama-1.1B-Chat-v1.0") + +# Inference is straightforward: +out = g(pipe, prompt=prompt).validated_output + +# `out` is a dict. Format it as JSON for readability: +import json +print(json.dumps(out, indent=2)) +``` + +### JSON Mode + +For models that support JSON through an input argument(`gpt-4o`, `gpt-4-turbo`, or `gpt-3.5-turbo`) + +```py +messages[-1]["content"]+=""" + +${gr.complete_json_suffix_v3} +""" +response = guard( + model="gpt-4o", + messages=messages, + prompt_params={"chat_history": chat_history}, + response_format={ "type": "json_object" } +) +``` \ No newline at end of file diff --git a/docs/how_to_guides/logs.md b/docs/how_to_guides/logs.md index 13b4bc1ea..a503625af 100644 --- a/docs/how_to_guides/logs.md +++ b/docs/how_to_guides/logs.md @@ -56,7 +56,7 @@ You are a human in an enchanted forest. You come across opponents of different t You run into a ${opp_type}. What do you do? -${gr.complete_json_suffix_v2} +${gr.complete_xml_suffix_v2} Here are a few examples diff --git a/docs/how_to_guides/using_llms.md b/docs/how_to_guides/using_llms.md new file mode 100644 index 000000000..d22038223 --- /dev/null +++ b/docs/how_to_guides/using_llms.md @@ -0,0 +1,249 @@ +# Using LLMs + +Guardrails has support for 100+ LLMs through its integration with LiteLLM. To interact with a model set the desired LLM API KEY such as the OPENAI_API_KEY and the desired model with the model property. Examples are below for some common ones. + +## OpenAI + +### Basic Usage + +```python +from guardrails import Guard + +os.environ["OPENAI_API_KEY"] = "YOUR_OPEN_AI_API_KEY" + +guard = Guard() + +result = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="gpt-4o", +) + +print(f"{result.validated_output}") +``` + +### Streaming + +```python +from guardrails import Guard + +os.environ["OPENAI_API_KEY"] = "YOUR_OPEN_AI_API_KEY" + +guard = Guard() + +stream_chunk_generator = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="gpt-4o", + stream=True, +) + +for chunk in stream_chunk_generator + print(f"{chunk.validated_output}") +``` + +### Tools/Function Calling + +```python +from pydantic import BaseModel, Field +from typing import List +from guardrails import Guard + +os.environ["OPENAI_API_KEY"] = "YOUR_OPEN_AI_API_KEY" + +class Fruit(BaseModel): + name: str + color: str + +class Basket(BaseModel): + fruits: List[Fruit] + +guard = Guard.from_pydantic(Basket) + +result = guard( + messages=[{"role":"user", "content":"Generate a basket of 5 fruits"}], + model="gpt-4o", + tools=guard.add_json_function_calling_tool([]), + tool_choice="required", +) + +print(f"{result.validated_output}") +``` + +## Anthropic + +### Basic Usage + +```python +from guardrails import Guard +import os + +guard = Guard() + +os.environ["ANTHROPIC_API_KEY"] = "your-api-key" + +result = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="claude-3-opus-20240229" +) + +print(f"{result.validated_output}") +``` + +### Streaming + +```python +from guardrails import Guard +import os + +os.environ["ANTHROPIC_API_KEY"] = "your-api-key" + +guard = Guard() + +stream_chunk_generator = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="claude-3-opus-20240229", + stream=True, +) + +for chunk in stream_chunk_generator + print(f"{chunk.validated_output}") +``` + +## Azure OpenAI + +### Basic Usage + +```python +from guardrails import Guard +import os +os.environ["AZURE_API_KEY"] = "" # "my-azure-api-key" +os.environ["AZURE_API_BASE"] = "" # "https://example-endpoint.openai.azure.com" +os.environ["AZURE_API_VERSION"] = "" # "2023-05-15" + +guard = Guard() + +result = guard( + model="azure/", + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], +) + +print(f"{result.validated_output}") +``` + +### Streaming + +```python +from guardrails import Guard + +os.environ["AZURE_API_KEY"] = "" # "my-azure-api-key" +os.environ["AZURE_API_BASE"] = "" # "https://example-endpoint.openai.azure.com" +os.environ["AZURE_API_VERSION"] = "" # "2023-05-15" + +guard = Guard() + +stream_chunk_generator = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="azure/", + stream=True +) + +for chunk in stream_chunk_generator + print(f"{chunk.validated_output}") +``` + +### Tools/Function Calling + +```python +from pydantic import BaseModel, Field +from typing import List +from guardrails import Guard + +os.environ["AZURE_API_KEY"] = "" # "my-azure-api-key" +os.environ["AZURE_API_BASE"] = "" # "https://example-endpoint.openai.azure.com" +os.environ["AZURE_API_VERSION"] = "" # "2023-05-15" + +class Fruit(BaseModel): + name: str + color: str + +class Basket(BaseModel): + fruits: List[Fruit] + +guard = Guard.from_pydantic(Basket) + +result = guard( + messages=[{"role":"user", "content":"Generate a basket of 5 fruits"}], + model="azure/", + tools=guard.add_json_function_calling_tool([]), + tool_choice="required", +) + +print(f"{result.validated_output}") +``` + +## Gemini + +### Basic Usage + +```python +from guardrails import Guard +import os + +os.environ['GEMINI_API_KEY'] = "" +guard = Guard() + +result = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="gemini/gemini-pro" +) + +print(f"{result.validated_output}") +``` + +### Streaming + +```python +from guardrails import Guard +import os + +os.environ['GEMINI_API_KEY'] = "" +guard = Guard() +stream_chunk_generator = guard( + messages=[{"role":"user", "content":"How many moons does Jupiter have?"}], + model="gemini/gemini-pro", + stream=True +) + +for chunk in stream_chunk_generator + print(f"{chunk.validated_output}") +``` + +### COMING SOON - Tools/Function calling + +```python +from pydantic import BaseModel, Field +from typing import List +from guardrails import Guard + +os.environ['GEMINI_API_KEY'] = "" + +class Fruit(BaseModel): + name: str + color: str + +class Basket(BaseModel): + fruits: List[Fruit] + +guard = Guard.from_pydantic(Basket) + +result = guard( + messages=[{"role":"user", "content":"Generate a basket of 5 fruits"}], + model="gemini/gemini-pro" + tools=guard.add_json_function_calling_tool([]) +) + +print(f"{result.validated_output}") +``` + +## Other LLMs + +See LiteLLM’s documentation [here](https://docs.litellm.ai/docs/providers) for details on many other llms. \ No newline at end of file diff --git a/docs/hub/api_reference_markdown/validators.md b/docs/hub/api_reference_markdown/validators.md index 09a9ca7c6..57a2276bb 100644 --- a/docs/hub/api_reference_markdown/validators.md +++ b/docs/hub/api_reference_markdown/validators.md @@ -1,1153 +1,2 @@ # Validators -## TwoWords - -Validates that a value is two words. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `two-words` | -| Supported data types | `string` | -| Programmatic fix | Pick the first two words. | - -## ExtractiveSummary - -Validates that a string is a valid extractive summary of a given -document. - -This validator does a fuzzy match between the sentences in the -summary and the sentences in the document. Each sentence in the -summary must be similar to at least one sentence in the document. -After the validation, the summary is updated to include the -sentences from the document that were matched, and the citations for -those sentences are added to the end of the summary. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `extractive-summary` | -| Supported data types | `string` | -| Programmatic fix | Remove any sentences that can not be verified. | - -**Arguments**: - - -- `threshold` - The minimum fuzz ratio to be considered summarized. Defaults to 85. - - Other parameters: Metadata - -- `filepaths` _List[str]_ - A list of strings that specifies the filepaths for any documents that should be used for asserting the summary's similarity. - -#### validate(value: Any, metadata: Dict) - -```python -def validate(value: Any, metadata: Dict) -> ValidationResult -``` - -Make sure each sentence was precisely copied from the document. - -## SaliencyCheck - -Checks that the summary covers the list of topics present in the -document. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `saliency-check` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - - -- `docs_dir` - Path to the directory containing the documents. -- `threshold` - Threshold for overlap between topics in document and summary. Defaults to 0.25 - -#### \_\_init\_\_(docs\_dir: str, llm\_callable: Optional[Callable] = None, on\_fail: Optional[Callable] = None, threshold: float = 0.25, \*\*kwargs) - -```python -def __init__(docs_dir: str, - llm_callable: Optional[Callable] = None, - on_fail: Optional[Callable] = None, - threshold: float = 0.25, - **kwargs) -``` - -Initialize the SalienceCheck validator. - -**Arguments**: - -- `docs_dir` - Path to the directory containing the documents. -- `on_fail` - Function to call when validation fails. -- `threshold` - Threshold for overlap between topics in document and summary. - -## BugFreeSQL - -Validates that there are no SQL syntactic bugs in the generated code. - -This is a very minimal implementation that uses the Pypi `sqlvalidator` package -to check if the SQL query is valid. You can implement a custom SQL validator -that uses a database connection to check if the query is valid. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `bug-free-sql` | -| Supported data types | `string` | -| Programmatic fix | None | - -## RemoveRedundantSentences - -Removes redundant sentences from a string. - -This validator removes sentences from a string that are similar to -other sentences in the string. This is useful for removing -repetitive sentences from a string. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `remove-redundant-sentences` | -| Supported data types | `string` | -| Programmatic fix | Remove any redundant sentences. | - -**Arguments**: - - -- `threshold` - The minimum fuzz ratio to be considered redundant. Defaults to 70. - -#### validate(value: Any, metadata: Dict) - -```python -def validate(value: Any, metadata: Dict) -> ValidationResult -``` - -Remove redundant sentences from a string. - -## DetectSecrets - -Validates whether the generated code snippet contains any secrets. - -**Key Properties** -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `detect-secrets` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - - None - - This validator uses the detect-secrets library to check whether the generated code - snippet contains any secrets. If any secrets are detected, the validator fails and - returns the generated code snippet with the secrets replaced with asterisks. - Else the validator returns the generated code snippet. - - Following are some caveats: - - Multiple secrets on the same line may not be caught. e.g. - - Minified code - - One-line lists/dictionaries - - Multi-variable assignments - - Multi-line secrets may not be caught. e.g. - - RSA/SSH keys - - -**Example**: - - ```py - - guard = Guard.from_string(validators=[ - DetectSecrets(on_fail=OnFailAction.FIX) - ]) - guard.parse( - llm_output=code_snippet, - ) - ``` - -#### get\_unique\_secrets(value: str) - -```python -def get_unique_secrets(value: str) -> Tuple[Dict[str, Any], List[str]] -``` - -Get unique secrets from the value. - -**Arguments**: - -- `value` _str_ - The generated code snippet. - - -**Returns**: - -- `unique_secrets` _Dict[str, Any]_ - A dictionary of unique secrets and their - line numbers. -- `lines` _List[str]_ - The lines of the generated code snippet. - -#### get\_modified\_value(unique\_secrets: Dict[str, Any], lines: List[str]) - -```python -def get_modified_value(unique_secrets: Dict[str, Any], - lines: List[str]) -> str -``` - -Replace the secrets on the lines with asterisks. - -**Arguments**: - -- `unique_secrets` _Dict[str, Any]_ - A dictionary of unique secrets and their - line numbers. -- `lines` _List[str]_ - The lines of the generated code snippet. - - -**Returns**: - -- `modified_value` _str_ - The generated code snippet with secrets replaced with - asterisks. - -## ValidRange - -Validates that a value is within a range. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `valid-range` | -| Supported data types | `integer`, `float`, `percentage` | -| Programmatic fix | Closest value within the range. | - -**Arguments**: - -- `min` - The inclusive minimum value of the range. -- `max` - The inclusive maximum value of the range. - -#### validate(value: Any, metadata: Dict) - -```python -def validate(value: Any, metadata: Dict) -> ValidationResult -``` - -Validates that a value is within a range. - -## ExtractedSummarySentencesMatch - -Validates that the extracted summary sentences match the original text -by performing a cosine similarity in the embedding space. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `extracted-summary-sentences-match` | -| Supported data types | `string` | -| Programmatic fix | Remove any sentences that can not be verified. | - -**Arguments**: - - -- `threshold` - The minimum cosine similarity to be considered similar. Default to 0.7. - - Other parameters: Metadata - -- `filepaths` _List[str]_ - A list of strings that specifies the filepaths for any documents that should be used for asserting the summary's similarity. -- `document_store` _DocumentStoreBase, optional_ - The document store to use during validation. Defaults to EphemeralDocumentStore. -- `vector_db` _VectorDBBase, optional_ - A vector database to use for embeddings. Defaults to Faiss. -- `embedding_model` _EmbeddingBase, optional_ - The embeddig model to use. Defaults to OpenAIEmbedding. - -## CompetitorCheck - -Validates that LLM-generated text is not naming any competitors from a -given list. - -In order to use this validator you need to provide an extensive list of the -competitors you want to avoid naming including all common variations. - -**Arguments**: - -- `competitors` _List[str]_ - List of competitors you want to avoid naming - -#### exact\_match(text: str, competitors: List[str]) - -```python -def exact_match(text: str, competitors: List[str]) -> List[str] -``` - -Performs exact match to find competitors from a list in a given -text. - -**Arguments**: - -- `text` _str_ - The text to search for competitors. -- `competitors` _list_ - A list of competitor entities to match. - - -**Returns**: - -- `list` - A list of matched entities. - -#### perform\_ner(text: str, nlp) - -```python -def perform_ner(text: str, nlp) -> List[str] -``` - -Performs named entity recognition on text using a provided NLP -model. - -**Arguments**: - -- `text` _str_ - The text to perform named entity recognition on. -- `nlp` - The NLP model to use for entity recognition. - - -**Returns**: - -- `entities` - A list of entities found. - -#### is\_entity\_in\_list(entities: List[str], competitors: List[str]) - -```python -def is_entity_in_list(entities: List[str], competitors: List[str]) -> List -``` - -Checks if any entity from a list is present in a given list of -competitors. - -**Arguments**: - -- `entities` _list_ - A list of entities to check -- `competitors` _list_ - A list of competitor names to match - - -**Returns**: - -- `List` - List of found competitors - -#### validate(value: str, metadata=Dict) - -```python -def validate(value: str, metadata=Dict) -> ValidationResult -``` - -Checks a text to find competitors' names in it. - -While running, store sentences naming competitors and generate a fixed output -filtering out all flagged sentences. - -**Arguments**: - -- `value` _str_ - The value to be validated. -- `metadata` _Dict, optional_ - Additional metadata. Defaults to empty dict. - - -**Returns**: - -- `ValidationResult` - The validation result. - -## BugFreePython - -Validates that there are no Python syntactic bugs in the generated code. - -This validator checks for syntax errors by running `ast.parse(code)`, -and will raise an exception if there are any. -Only the packages in the `python` environment are available to the code snippet. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `bug-free-python` | -| Supported data types | `string` | -| Programmatic fix | None | - -## LowerCase - -Validates that a value is lower case. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `lower-case` | -| Supported data types | `string` | -| Programmatic fix | Convert to lower case. | - -## EndsWith - -Validates that a list ends with a given value. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `ends-with` | -| Supported data types | `list` | -| Programmatic fix | Append the given value to the list. | - -**Arguments**: - -- `end` - The required last element. - -## QARelevanceLLMEval - -Validates that an answer is relevant to the question asked by asking the -LLM to self evaluate. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `qa-relevance-llm-eval` | -| Supported data types | `string` | -| Programmatic fix | None | - -Other parameters: Metadata -question (str): The original question the llm was given to answer. - -## ValidURL - -Validates that a value is a valid URL. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `valid-url` | -| Supported data types | `string` | -| Programmatic fix | None | - -## SqlColumnPresence - -Validates that all columns in the SQL query are present in the schema. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `sql-column-presence` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - -- `cols` - The list of valid columns. - -## ValidChoices - -Validates that a value is within the acceptable choices. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `valid-choices` | -| Supported data types | `all` | -| Programmatic fix | None | - -**Arguments**: - -- `choices` - The list of valid choices. - -#### validate(value: Any, metadata: Dict) - -```python -def validate(value: Any, metadata: Dict) -> ValidationResult -``` - -Validates that a value is within a range. - -## ReadingTime - -Validates that the a string can be read in less than a certain amount of -time. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `reading-time` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - - -- `reading_time` - The maximum reading time in minutes. - -## IsProfanityFree - -Validates that a translated text does not contain profanity language. - -This validator uses the `alt-profanity-check` package to check if a string -contains profanity language. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `is-profanity-free` | -| Supported data types | `string` | -| Programmatic fix | None | - -## ValidLength - -Validates that the length of value is within the expected range. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `length` | -| Supported data types | `string`, `list`, `object` | -| Programmatic fix | If shorter than the minimum, pad with empty last elements. If longer than the maximum, truncate. | - -**Arguments**: - -- `min` - The inclusive minimum length. -- `max` - The inclusive maximum length. - -#### validate(value: Union[str, List], metadata: Dict) - -```python -def validate(value: Union[str, List], metadata: Dict) -> ValidationResult -``` - -Validates that the length of value is within the expected range. - -## SimilarToList - -Validates that a value is similar to a list of previously known values. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `similar-to-list` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - -- `standard_deviations` _int_ - The number of standard deviations from the mean to check. -- `threshold` _float_ - The threshold for the average semantic similarity for strings. - - For integer values, this validator checks whether the value lies - within 'k' standard deviations of the mean of the previous values. - (Assumes that the previous values are normally distributed.) For - string values, this validator checks whether the average semantic - similarity between the generated value and the previous values is - less than a threshold. - -#### get\_semantic\_similarity(text1: str, text2: str, embed\_function: Callable) - -```python -def get_semantic_similarity(text1: str, text2: str, - embed_function: Callable) -> float -``` - -Get the semantic similarity between two strings. - -**Arguments**: - -- `text1` _str_ - The first string. -- `text2` _str_ - The second string. -- `embed_function` _Callable_ - The embedding function. - -**Returns**: - -- `similarity` _float_ - The semantic similarity between the two strings. - -## PydanticFieldValidator - -Validates a specific field in a Pydantic model with the specified -validator method. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `pydantic_field_validator` | -| Supported data types | `Any` | -| Programmatic fix | Override with return value from `field_validator`. | - -**Arguments**: - - -- `field_validator` _Callable_ - A validator for a specific field in a Pydantic model. - -## PIIFilter - -Validates that any text does not contain any PII. - -This validator uses Microsoft's Presidio (https://github.com/microsoft/presidio) -to detect PII in the text. If PII is detected, the validator will fail with a -programmatic fix that anonymizes the text. Otherwise, the validator will pass. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `pii` | -| Supported data types | `string` | -| Programmatic fix | Anonymized text with PII filtered | - -**Arguments**: - -- `pii_entities` _str | List[str], optional_ - The PII entities to filter. Must be - one of `pii` or `spi`. Defaults to None. Can also be set in metadata. - -#### get\_anonymized\_text(text: str, entities: List[str]) - -```python -def get_anonymized_text(text: str, entities: List[str]) -> str -``` - -Analyze and anonymize the text for PII. - -**Arguments**: - -- `text` _str_ - The text to analyze. -- `pii_entities` _List[str]_ - The PII entities to filter. - - -**Returns**: - -- `anonymized_text` _str_ - The anonymized text. - -## OnTopic - -Checks if text's main topic is specified within a list of valid topics -and ensures that the text is not about any of the invalid topics. - -This validator accepts at least one valid topic and an optional list of -invalid topics. - -Default behavior first runs a Zero-Shot model, and then falls back to -ask OpenAI's `gpt-3.5-turbo` if the Zero-Shot model is not confident -in the topic classification (score < 0.5). - -In our experiments this LLM fallback increases accuracy by 15% but also -increases latency (more than doubles the latency in the worst case). - -Both the Zero-Shot classification and the GPT classification may be toggled. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ---------------------------------------- | -| Name for `format` attribute | `on_topic` | -| Supported data types | `string` | -| Programmatic fix | Removes lines with off-topic information | - -**Arguments**: - -- `valid_topics` _List[str]_ - topics that the text should be about - (one or many). -- `invalid_topics` _List[str], Optional, defaults to []_ - topics that the - text cannot be about. -- `device` _int, Optional, defaults to -1_ - Device ordinal for CPU/GPU - supports for Zero-Shot classifier. Setting this to -1 will leverage - CPU, a positive will run the Zero-Shot model on the associated CUDA - device id. -- `model` _str, Optional, defaults to 'facebook/bart-large-mnli'_ - The - Zero-Shot model that will be used to classify the topic. See a - list of all models here: - https://huggingface.co/models?pipeline_tag=zero-shot-classification - llm_callable (Union[str, Callable, None], Optional, defaults to -- `'gpt-3.5-turbo')` - Either the name of the OpenAI model, or a callable - that takes a prompt and returns a response. -- `disable_classifier` _bool, Optional, defaults to False_ - controls whether - to use the Zero-Shot model. At least one of disable_classifier and - disable_llm must be False. -- `disable_llm` _bool, Optional, defaults to False_ - controls whether to use - the LLM fallback. At least one of disable_classifier and - disable_llm must be False. -- `model_threshold` _float, Optional, defaults to 0.5_ - The threshold used to - determine whether to accept a topic from the Zero-Shot model. Must be - a number between 0 and 1. - -#### call\_llm(text: str, topics: List[str]) - -```python -@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(5)) -def call_llm(text: str, topics: List[str]) -> str -``` - -Call the LLM with the given prompt. - -Expects a function that takes a string and returns a string. - -**Arguments**: - -- `text` _str_ - The input text to classify using the LLM. -- `topics` _List[str]_ - The list of candidate topics. - -**Returns**: - -- `response` _str_ - String representing the LLM response. - -#### set\_callable(llm\_callable: Union[str, Callable, None]) - -```python -def set_callable(llm_callable: Union[str, Callable, None]) -> None -``` - -Set the LLM callable. - -**Arguments**: - -- `llm_callable` - Either the name of the OpenAI model, or a callable that takes - a prompt and returns a response. - -## UpperCase - -Validates that a value is upper case. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `upper-case` | -| Supported data types | `string` | -| Programmatic fix | Convert to upper case. | - -## ProvenanceV0 - -Validates that LLM-generated text matches some source text based on -distance in embedding space. - -**Key Properties** - -| Property | Description | -| ----------------------------- | ----------------------------------- | -| Name for `format` attribute | `provenance-v0` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - -- `threshold` - The minimum cosine similarity between the generated text and - the source text. Defaults to 0.8. -- `validation_method` - Whether to validate at the sentence level or over the full text. Must be one of `sentence` or `full`. Defaults to `sentence` - - Other parameters: Metadata -- `query_function` _Callable, optional_ - A callable that takes a string and returns a list of (chunk, score) tuples. -- `sources` _List[str], optional_ - The source text. -- `embed_function` _Callable, optional_ - A callable that creates embeddings for the sources. Must accept a list of strings and return an np.array of floats. - - In order to use this validator, you must provide either a `query_function` or - `sources` with an `embed_function` in the metadata. - - If providing query_function, it should take a string as input and return a list of - (chunk, score) tuples. The chunk is a string and the score is a float representing - the cosine distance between the chunk and the input string. The list should be - sorted in ascending order by score. - -- `Note` - The score should represent distance in embedding space, not similarity. I.e., - lower is better and the score should be 0 if the chunk is identical to the input - string. - - -**Example**: - - ```py - def query_function(text: str, k: int) -> List[Tuple[str, float]]: - return [("This is a chunk", 0.9), ("This is another chunk", 0.8)] - - guard = Guard.from_rail(...) - guard( - openai.ChatCompletion.create(...), - prompt_params={...}, - temperature=0.0, - metadata={"query_function": query_function}, - ) - ``` - - - If providing sources, it should be a list of strings. The embed_function should - take a string or a list of strings as input and return a np array of floats. - The vector should be normalized to unit length. - - -**Example**: - - ```py - def embed_function(text: Union[str, List[str]]) -> np.ndarray: - return np.array([[0.1, 0.2, 0.3]]) - - guard = Guard.from_rail(...) - guard( - openai.ChatCompletion.create(...), - prompt_params={...}, - temperature=0.0, - metadata={ - "sources": ["This is a source text"], - "embed_function": embed_function - }, - ) - ``` - -## ProvenanceV1 - -Validates that the LLM-generated text is supported by the provided -contexts. - -This validator uses an LLM callable to evaluate the generated text against the -provided contexts (LLM-ception). - -In order to use this validator, you must provide either: -1. a 'query_function' in the metadata. That function should take a string as input -(the LLM-generated text) and return a list of relevant -chunks. The list should be sorted in ascending order by the distance between the -chunk and the LLM-generated text. - -Example using str callable: - - -Example using a custom llm callable: - - -OR - -2. `sources` with an `embed_function` in the metadata. The embed_function should -take a string or a list of strings as input and return a np array of floats. -The vector should be normalized to unit length. - -``` py -def query_function(text: str, k: int) -> List[str]: - return ["This is a chunk", "This is another chunk"] - -guard = Guard.from_string(validators=[ - ProvenanceV1(llm_callable="gpt-3.5-turbo", ...) -]) -guard.parse( - llm_output=..., - metadata={"query_function": query_function} -) -``` -``` py -def query_function(text: str, k: int) -> List[str]: - return ["This is a chunk", "This is another chunk"] - -guard = Guard.from_string(validators=[ - ProvenanceV1(llm_callable=your_custom_callable, ...) - ] -) -guard.parse( - llm_output=..., - metadata={"query_function": query_function} -) -``` - -**Example**: - - -```py -def embed_function(text: Union[str, List[str]]) -> np.ndarray: - return np.array([[0.1, 0.2, 0.3]]) - -guard = Guard.from_rail(...) -guard( - openai.ChatCompletion.create(...), - prompt_params={...}, - temperature=0.0, - metadata={ - "sources": ["This is a source text"], - "embed_function": embed_function - }, -) -``` - -#### \_\_init\_\_(validation\_method: str = "sentence", llm\_callable: Union[str, Callable] = "gpt-3.5-turbo", top\_k: int = 3, max\_tokens: int = 2, on\_fail: Optional[Callable] = None, \*\*kwargs) - -```python -def __init__(validation_method: str = "sentence", - llm_callable: Union[str, Callable] = "gpt-3.5-turbo", - top_k: int = 3, - max_tokens: int = 2, - on_fail: Optional[Callable] = None, - **kwargs) -``` - -args: -validation_method (str): Whether to validate at the sentence level or over -the full text. One of `sentence` or `full`. Defaults to `sentence` -llm_callable (Union[str, Callable]): Either the name of the OpenAI model, -or a callable that takes a prompt and returns a response. -top_k (int): The number of chunks to return from the query function. -Defaults to 3. -max_tokens (int): The maximum number of tokens to send to the LLM. -Defaults to 2. - -Other args: Metadata -query_function (Callable): A callable that takes a string and returns a -list of chunks. -sources (List[str], optional): The source text. -embed_function (Callable, optional): A callable that creates embeddings for -the sources. Must accept a list of strings and returns float np.array. - -#### set\_callable(llm\_callable: Union[str, Callable]) - -```python -def set_callable(llm_callable: Union[str, Callable]) -> None -``` - -Set the LLM callable. - -**Arguments**: - -- `llm_callable` - Either the name of the OpenAI model, or a callable that takes - a prompt and returns a response. - -#### call\_llm(prompt: str) - -```python -@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6)) -def call_llm(prompt: str) -> str -``` - -Call the LLM with the given prompt. - -Expects a function that takes a string and returns a string. - -**Arguments**: - -- `prompt` _str_ - The prompt to send to the LLM. - - -**Returns**: - -- `response` _str_ - String representing the LLM response. - -#### evaluate\_with\_llm(text: str, query\_function: Callable) - -```python -def evaluate_with_llm(text: str, query_function: Callable) -> bool -``` - -Validate that the LLM-generated text is supported by the provided -contexts. - -**Arguments**: - -- `value` _Any_ - The LLM-generated text. -- `query_function` _Callable_ - The query function. - - -**Returns**: - -- `self_eval` - The self-evaluation boolean - -## RegexMatch - -Validates that a value matches a regular expression. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `regex_match` | -| Supported data types | `string` | -| Programmatic fix | Generate a string that matches the regular expression | - -**Arguments**: - -- `regex` - Str regex pattern -- `match_type` - Str in {"search", "fullmatch"} for a regex search or full-match option - -## ExcludeSqlPredicates - -Validates that the SQL query does not contain certain predicates. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `exclude-sql-predicates` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - -- `predicates` - The list of predicates to avoid. - -## SimilarToDocument - -Validates that a value is similar to the document. - -This validator checks if the value is similar to the document by checking -the cosine similarity between the value and the document, using an -embedding. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `similar-to-document` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - -- `document` - The document to use for the similarity check. -- `threshold` - The minimum cosine similarity to be considered similar. Defaults to 0.7. -- `model` - The embedding model to use. Defaults to text-embedding-ada-002. - -#### cosine\_similarity(a: "np.ndarray", b: "np.ndarray") - -```python -@staticmethod -def cosine_similarity(a: "np.ndarray", b: "np.ndarray") -> float -``` - -Calculate the cosine similarity between two vectors. - -**Arguments**: - -- `a` - The first vector. -- `b` - The second vector. - - -**Returns**: - -- `float` - The cosine similarity between the two vectors. - -## IsHighQualityTranslation - -Validates that the translation is of high quality. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `is-high-quality-translation` | -| Supported data types | `string` | -| Programmatic fix | None | - -Other parameters: Metadata -translation_source (str): The source of the translation. - -This validator uses one of the reference-free models from Unbabel/COMET -to check the quality of the translation. Specifically, it uses the -`Unbabel/wmt22-cometkiwi-da` model. - -Unbabel/COMET details: https://github.com/Unbabel/COMET -Model details: https://huggingface.co/Unbabel/wmt22-cometkiwi-da - -Pre-requisites: -- Install the `unbabel-comet` from source: -`pip install git+https://github.com/Unbabel/COMET` -- Please accept the model license from: -https://huggingface.co/Unbabel/wmt22-cometkiwi-da -- Login into Huggingface Hub using: -huggingface-cli login --token $HUGGINGFACE_TOKEN - -## EndpointIsReachable - -Validates that a value is a reachable URL. - -**Key Properties** - -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `is-reachable` | -| Supported data types | `string`, | -| Programmatic fix | None | - -## ToxicLanguage - -Validates that the generated text is toxic. - -**Key Properties** -| Property | Description | -| ----------------------------- | --------------------------------- | -| Name for `format` attribute | `toxic-language` | -| Supported data types | `string` | -| Programmatic fix | None | - -**Arguments**: - -- `threshold` - The confidence threshold (model inference) for toxicity. - Defaults to 0.5. -- `validation_method` - Whether to validate at the sentence level or - over the full text. Must be one of `sentence` or `full`. - Defaults to `sentence` - - This validator uses the pre-trained multi-label model from HuggingFace - - `unitary/unbiased-toxic-roberta` to check whether the generated text is toxic. - If the model predicts any label of: `toxicity`, `severe_toxicity`, - `obscene`, `threat`, `insult`, `identity_attack`, or `sexual_explicit` with - confidence higher than the specified threshold, the validator fails and returns - the generated text with the toxic sentences / entire text removed. Else the - validator returns the generated text as it is. - - If validation_method is `sentence`, the validator will remove the sentences - that are predicted to be toxic and return the remaining sentences. If - validation_method is `full`, the validator will remove the entire text if - the prediction is deemed toxic and return an empty string. - - In our experiments, a threshold of 0.5 worked best, hence set as default here. - However, you can try different values of threshold to see what works best for - your use case. - Link for experiments: https://wandb.ai/ml-guardrails/toxic-language-experiments - -#### get\_toxicity(value: str) - -```python -def get_toxicity(value: str) -> List[str] -``` - -Check whether the generated text is toxic. - -Returns the labels predicted by the model with -confidence higher than the threshold. - -**Arguments**: - -- `value` _str_ - The generated text. - - -**Returns**: - -- `pred_labels` _bool_ - Labels predicted by the model - with confidence higher than the threshold. - -#### validate\_each\_sentence(value: str, metadata: Dict[str, Any]) - -```python -def validate_each_sentence(value: str, - metadata: Dict[str, Any]) -> ValidationResult -``` - -Validate that each sentence in the generated text is toxic. - -#### validate\_full\_text(value: str, metadata: Dict[str, Any]) - -```python -def validate_full_text(value: str, metadata: Dict[str, - Any]) -> ValidationResult -``` - -Validate that the entire generated text is toxic. - -## OneLine - -Validates that a value is a single line, based on whether or not the -output has a newline character (\n). - -**Key Properties** - -| Property | Description | -| ----------------------------- | -------------------------------------- | -| Name for `format` attribute | `one-line` | -| Supported data types | `string` | -| Programmatic fix | Keep the first line, delete other text | - diff --git a/docs/hub/concepts/validators.md b/docs/hub/concepts/validators.md index 578b8b9f5..1530ec1a7 100644 --- a/docs/hub/concepts/validators.md +++ b/docs/hub/concepts/validators.md @@ -18,7 +18,7 @@ As an example, the `ExtractedSummarySentencesMatch` validator accepts a `filepat guard = Guard.from_rail("my_railspec.rail") outcome = guard( - llm_api=openai.ChatCompletion.create, + llm_api=openai.chat.completions.create, model="gpt-3.5-turbo", num_reasks=3, metadata={ diff --git a/docs/hub/how_to_guides/input_validation.md b/docs/hub/how_to_guides/input_validation.md index 2e04bab4d..b026e4be8 100644 --- a/docs/hub/how_to_guides/input_validation.md +++ b/docs/hub/how_to_guides/input_validation.md @@ -2,28 +2,35 @@ Validators that are tagged as input validators can be used to validate the input prompt before it is sent to the model. This can be useful for ensuring that the input prompt meets certain criteria, such as being on-topic, not containing PII, etc. -In order to use an input validator, first make sure that the validator is installed. You can install the validator using the `guardrails hub install` command. For example, to install the `two-words` validator, you can run: +In order to use an input validator, first make sure that the validator is installed. You can install the validator using the `guardrails hub install` command. For example, to install the `DetectPII` validator, you can run: ```bash guardrails hub install hub://guardrails/detect_pii ``` -Then, add the input validator to the `Guard` object using the `with_prompt_validation` method. For example, to use the `detect_pii` validator with OpenAI's GPT-3, you can run: +Then, add the input validator to the `Guard` object via the `use` method. For example, to use the `DetectPII` validator with OpenAI's GPT-3, you can run: ```python -from guardrails import Guard, ValidatorError +import openai +from guardrails import Guard +from guardrails.errors import ValidationError from guardrails.hub import DetectPII +from guardrails.types import OnFailAction guard = Guard() -guard.with_prompt_validation([DetectPII( - pii_entities=["EMAIL_ADDRESS", "PHONE_NUMBER"]) -]) +guard.use( + DetectPII( + pii_entities=["EMAIL_ADDRESS", "PHONE_NUMBER"], + on_fail=OnFailAction.EXCEPTION + ), + on="prompt" +) try: guard( openai.chat.completions.create, prompt="My email address is not_a_real_email@guardrailsai.com", ) -except ValidatorError as e: +except ValidationError as e: print(e) ``` diff --git a/docs/index.md b/docs/index.md index ae084ff68..18726aeed 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,4 @@ -# Guardrails AI +# Introduction ## What is Guardrails? diff --git a/docs/integrations/azure_openai.ipynb b/docs/integrations/azure_openai.ipynb index cb3cd20d2..9040ef06e 100644 --- a/docs/integrations/azure_openai.ipynb +++ b/docs/integrations/azure_openai.ipynb @@ -119,7 +119,7 @@ ], "source": [ "raw_llm_output, validated_output, *rest = guard(\n", - " openai.ChatCompletion.create,\n", + " openai.chat.completions.create,\n", " engine=os.environ.get(\"AZURE_OPENAI_API_ENGINE\"),\n", " max_tokens=1024,\n", " temperature=0.3\n", diff --git a/docs/integrations/langchain.ipynb b/docs/integrations/langchain.ipynb index b82d75042..37090e04d 100644 --- a/docs/integrations/langchain.ipynb +++ b/docs/integrations/langchain.ipynb @@ -57,7 +57,7 @@ "\n", "${doctors_notes}\n", "\n", - "${gr.complete_json_suffix_v2}\n", + "${gr.complete_xml_suffix_v2}\n", "\n", "\n", "\"\"\"" diff --git a/docs/integrations/openai_functions.ipynb b/docs/integrations/openai_functions.ipynb index 029dee8a9..e66d440aa 100644 --- a/docs/integrations/openai_functions.ipynb +++ b/docs/integrations/openai_functions.ipynb @@ -23,7 +23,6 @@ "outputs": [], "source": [ "import openai\n", - "import os\n", "\n", "from pydantic import BaseModel\n", "from rich import print\n", @@ -31,7 +30,9 @@ "\n", "import guardrails as gd\n", "\n", - "os.environ['OPENAI_API_KEY'] = \"YOUR_API_KEY\"" + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ['OPENAI_API_KEY'] = \"YOUR_API_KEY\"" ] }, { @@ -78,7 +79,7 @@ "guard = gd.Guard.from_pydantic(Director, prompt=\"Generate data about a movie director.\")\n", "\n", "raw_llm_output, validated_output, *rest = guard(\n", - " openai.ChatCompletion.create,\n", + " openai.chat.completions.create,\n", " model=\"gpt-4-0613\",\n", " max_tokens=1024,\n", " temperature=0.0,\n", diff --git a/docs/integrations/telemetry/grafana.mdx b/docs/integrations/telemetry/grafana.mdx new file mode 100644 index 000000000..3d3152713 --- /dev/null +++ b/docs/integrations/telemetry/grafana.mdx @@ -0,0 +1,140 @@ +import Dashboard from '../../how_to_guides/assets/dashboard.png'; +import ViewTraces from '../../how_to_guides/assets/view_traces.mp4'; +import GrafanaOtelConfig from '../../how_to_guides/assets/grafana_otel_config.mp4'; + +# Grafana + +## Overview + +In this document, we explain how to set up Guardrails with [OpenTelemetry (OTEL)](https://opentelemetry.io/) using either Grafana or a self-hosted OTEL collector. With this functionality enabled, you can measure latency of Guards, Large Language Models (LLMs), scuccess rates, and other metrics for your Guardrails-protected LLM calls. + +This guide will show how to set up your Python project to log traces to Grafana and to a self-hosted OTEL collector. For other OTEL endpoints, consult your metrics provider's documentation on OTEL support. + +**Note**: Please see our [Telemetry concepts doc](../../concepts/telemetry) to get an idea of what metrics you can capture using OTEL. + +## Configure OTEL for Grafana + +Grafana Cloud is a free offering by Grafana that's easy to setup and is our preferred location for storing metrics. + +### Get environment variables from Grafana + + + +1. Sign up with the Grafana cloud (it's free!) https://grafana.com/auth/sign-up/create-user. +2. Once your account is up, create a stack. +3. Navigate away to https://grafana.com/ and click the "My Account" button on the top right of the screen +4. Scroll down and click on the "Configure" button in the "Open Telemetry" section of the page +5. Click "generate token" +6. Compile the instance ID, token, and environment variables +GRAFANA_INSTANCE_ID +TOKEN +OTEL_EXPORTER_OTLP_PROTOCOL +OTEL_EXPORTER_OTLP_ENDPOINT +OTEL_EXPORTER_OTLP_HEADERS + +### Setup a Guard with Telemetry + +1. First, install the ```ValidLength``` guardrail from Guardrails Hub. + +```guardrails hub install hub://guardrails/valid_length``` + +2. Next, set up your Guard the default tracer provided in the guardrails library. You can still use your desired validators: + +
main.py
+```python +from guardrails import Guard, OnFailAction +from guardrails.utils.telemetry_utils import default_otlp_tracer +from guardrails.hub import ValidLength +import openai + +guard = Guard.from_string( + validators=[ValidLength(min=1, max=10, on_fail=OnFailAction.EXCEPTION)], + # use a descriptive name that will differentiate where your metrics are stored + tracer=default_otlp_tracer("petname_guard") +) + +guard( + llm_api=openai.chat.completions.create, + prompt="Suggest a name for my cat.", + model="gpt-4", + max_tokens=1024, + temperature=0.5, +) +``` + +3. Before running the file, make sure to set the environment variables you got from Grafana + +```bash +export GRAFANA_INSTANCE_ID= +export TOKEN= + +# these come from the 'copy environment variables' button +export OTEL_EXPORTER_OTLP_PROTOCOL= +export OTEL_EXPORTER_OTLP_ENDPOINT= +# IMPORTANT: Make sure to replace the space after "Basic" with "%20". +export OTEL_EXPORTER_OTLP_HEADERS= +``` + +4. Finally, run the python script + +```bash + +python main.py + +``` + +### View traces + +There are two ways to view traces: using the Explore tab or using the Guardrails Grafana dashboard template. + +#### Use the Explore tab + +The simplest way to do this is to go to your grafana stack and click on the "**Explore** tab. You should see a list of traces that you can filter by service name, operation name, and more. + + + +#### Use the Guardrails Grafana dashboard template + +While this is easy to do, it's not the best way to get a big-picture view of how your guards are doing. For that, we should use the Guardrails Grafana dashboard template. + +**[Use the template](https://grafana.com/grafana/dashboards/20600-standard-guardrails-dash/)** + +**[Template instructions](https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/import-dashboards/)** + + + + +## Configure OTEL for a self-hosted OpenTelemetry Collector + +For advanced use cases (like if you have a metrics provider in a VPC), you can use a self-hosted OpenTelemetry Collector to receive traces and metrics from your Guard. +Standard [open telemetry environment variables](https://opentelemetry.io/docs/languages/python/exporters/) are used to configure the collector. Use the `default_otel_collector_tracer` when configuring your guard. + +```python +from guardrails import Guard, OnFailAction +from guardrails.utils.telemetry_utils import default_otel_collector_tracer +from guardrails.hub import ValidLength +import openai + +guard = Guard().use( + validators=[ValidLength(min=1, max=10, on_fail=OnFailAction.EXCEPTION)], +) + +guard.configure( + # use a descriptive name that will differentiate where your metrics are stored + tracer=default_otel_collector_tracer("petname_guard") +) + +guard( + messages=[{ + "role": "user", + "content": "Suggest a name for my cat. + }], + model="gpt-4", + max_tokens=1024, + temperature=0.5, +) +``` \ No newline at end of file diff --git a/docs/llm_api_wrappers.md b/docs/llm_api_wrappers.md index 80fd31c1d..c62f6e090 100644 --- a/docs/llm_api_wrappers.md +++ b/docs/llm_api_wrappers.md @@ -19,9 +19,9 @@ guard = gd.Guard.from_rail(...) # Wrap openai API call raw_llm_output, guardrail_output, *rest = guard( - openai.Completion.create, + openai.completions.create, prompt_params={"prompt_param_1": "value_1", "prompt_param_2": "value_2", ..}, - engine="text-davinci-003", + model="gpt-3.5-turbo-instruct", max_tokens=100, temperature=0.0, ) @@ -38,7 +38,7 @@ guard = gd.Guard.from_rail(...) # Wrap openai API call raw_llm_output, guardrail_output, *rest = guard( - openai.ChatCompletion.create, + openai.chat.completions.create, prompt_params={"prompt_param_1": "value_1", "prompt_param_2": "value_2", ..}, system_prompt="You are a helpful assistant...", model="gpt-3.5-turbo", diff --git a/docs/migration_guides/0-5-migration.md b/docs/migration_guides/0-5-migration.md new file mode 100644 index 000000000..5a7ee81fd --- /dev/null +++ b/docs/migration_guides/0-5-migration.md @@ -0,0 +1,281 @@ +# Migrating to 0.5.0 + + +## New Features + +### Run Guardrails as a local server + +Guardrails 0.5.0 introduces the `start` command to the guardrails cli. This allows you to run the Guardrails validation engine as a local python server. + +Benefits of using Guardrails this way include: + +- Less strain on your main process/thread +- The Guardrails server utilizes Gunicorn to take advantage of multiple threads + - Supported on Linux and MacOS by default, supported on Windows when using WSL +- Declare your Guards in a separate config and reference them by name in your app to keep your code slim and clean + +Example: + +1. Install +```sh +pip install "guardarils-ai>=0.5.0" +guardrails hub install hub://guardrails/regex_match +``` + +2. Create a `config.py` +```py +from guardrails import Guard +from guardrails.hub import RegexMatch + + +Guard( + name='name-case', + description='Checks that a string is in Name Case format.' +).use( + RegexMatch(regex="^[A-Z][a-z\\s]*$") +) +``` + +3. Start the Guardrails server +```sh +guardrails start --config=config.py +``` + +4. Use the Guard in your application +```py +from rich import print +from guardrails import Guard + +name_case = Guard(name='name-case') + +result = name_case.validate("Zayd") + +print(result) +``` + + +### Generate structured data with smaller models: + +As part of Guardrails 0.5.0, we're launching constrained decoding support for HuggingFace models. This allow you to generate structured data that matches your schema with confidence. + +Example: +```py +from guardrails import Guard +from pydantic import BaseModel + +class Dog(BaseModel): + name: str + color: str + weight_kg: float + +class NewFriends(BaseModel): + dogs: list[Dog] + +guard = Guard.from_pydantic(NewFriends, output_formatter="jsonformer") + +# JSONFormer is only compatible with HF Pipelines and HF Models: +from transformers import pipeline +tiny_llama_pipeline = pipeline("text-generation", "TinyLlama/TinyLlama-1.1B-Chat-v1.0") + +# Inference is straightforward: +response = guard(tiny_llama_pipeline, prompt="Please enjoy this list of good dogs:") + +# `out` is a dict. Format it as JSON for readability: +import json +print(json.dumps(response.validated_output, indent=2)) +``` + + +## Improvements + +### LiteLLM is now easier to use within Guardrails + +When calling models through LiteLLM, specifying the `llm_api` argument is now optional. Instead, just pass the model name. + +Example: + +```py +from rich import print +from guardrails import Guard +from guardrails.hub import RegexMatch + +guard = Guard().use(RegexMatch("95", match_type="search")) + +response = guard( + model="gpt-4o", + instructions="You are a helpful assistant.", + prompt="How many moons does jupiter have?", +) + +print(response) +``` + +### New public interface for generating JSON schema-based function calling tools + +Guardrails has supported function calling for OpenAI Chat models for a while and previously would auto-insert a function to specify the schema when a Guard was created via a Pydantic model. + +In Guardrails 0.5.0, you can use this same pattern regardless of how the Guard was initialized. We also made the process more transparent by allowing you to generate the tool first and decide when to pass it as a keyword argument. For models that support openai tool/function calling (`gpt-4o`, `gpt-4-turbo`, or `gpt-3.5-turbo`), you can extend your existing `tools` with `Guard.json_function_calling_tool()` + +Example: +```py +from guardrails import Guard +from guardrails.hub import RegexMatch +from pydantic import BaseModel, Field +from typing import List + +NAME_REGEX = "^[A-Z][a-z]+\s[A-Z][a-z]+$" + +class Delivery(BaseModel): + custome_name: str=Field(validators=[RegexMatch(regex=NAME_REGEX)], description="customer name") + pickup_time: str=Field(description="date and time of pickup") + pickup_location: str=Field(description="address of pickup") + dropoff_time: str=Field(description="date and time of dropoff") + dropoff_location: str=Field(description="address of dropoff") + price: str = Field(description="price of delivery with currency symbol included") + +class Schedule(BaseModel): + deliveries: List[Delivery] + +guard = Guard.from_pydantic(Schedule) +chat_history=""" +nelson and murdock: i need a pickup 797 9th Avenue, manila envelope, June 3 10:00am with dropoff 10:30am Courthouse, 61 Center Street C/O frank james +operator: quote - $23.00 +neslon and murdock: perfect, we accept the quote +operator: 797 9th ave, 10:00am pickup comfirmed +abc flowers: i need a pickup of a flowers from abc flowers at 21 3rd street at 11:00am on june 2 with a dropoff at 75th Ave at 5:30pm same day +operator: 21 3rd street flowers quote - $14.50 +abc flowers: accepted +polk and wardell: i need a pickup of a bagels from Bakers Co at 331 5th street at 11:00am on june 3 with a dropoff at 75th Ave at 5:30pm same day +operator: 331 5th street bagels quote - $34.50 +polk and wardell: accepted +""" + +prompt = """ +From the chat exchanges below extract a schedule of deliveries. +Chats: +${chat_history} +""" + +tools = [] # an open ai compatible list of tools + +response = guard( + openai.chat.completions.create, + model="gpt-4o", + instructions="You are a helpful assistant.", + prompt=prompt, + prompt_params={"chat_history": chat_history}, + tools=guard.json_function_calling_tool(tools), + tool_choice="required", +) +``` + +### `Guard.use()` now works for all Guards + +Previously, constructing a Guard via the `use` method was only supported for unstructured response schemas. It now supports specifying validators for any Guard regardless of the initialization method (`Guard()`, `Guard.from_rail()`, `Guard.from_pydantic()`, etc.). `Guard.use()` is also the new method of applying input validations to a Guard. + +Example of applying input validation to the Prompt: +```py +import openai +from guardrails import Guard +from guardrails.errors import ValidationError +from guardrails.hub import DetectPII +from guardrails.types import OnFailAction + +guard = Guard() +guard.use( + DetectPII( + pii_entities=["EMAIL_ADDRESS", "PHONE_NUMBER"], + on_fail=OnFailAction.EXCEPTION + ), + on="prompt" +) + +try: + guard( + openai.chat.completions.create, + prompt="My email address is not_a_real_email@guardrailsai.com", + ) +except ValidationError as e: + print(e) +``` + +To utilize `Guard.use()` on a Guard with structured output, you can specify a JSON Path to identify which property the Validator(s) should be assigned to. + +Example: +```py +import json +from pydantic import BaseModel, Field +from guardrails import Guard, OnFailAction +from guardrails.errors import ValidationError +from guardrails.hub import RegexMatch, ValidRange + +class Person(BaseModel): + name: str + # Existing way of assigning validators; still valid + age: int = Field(validators=[ValidRange(0, 100, on_fail=OnFailAction.EXCEPTION)]) + is_employed: bool + +guard = Guard.from_pydantic(Person) + +# Use a regex to make sure the name is Title Case +guard.use( + RegexMatch("^(?:[A-Z][^\\s]*\\s?)+$", on_fail=OnFailAction.EXCEPTION), + on="$.name" +) + +try: + guard.validate(json.dumps({ + "name": "john doe", + "age": 30, + "is_employed": True + })) +except ValidationError as e: + print(e) +``` + +## Backwards-incompatible changes + +### Args vs Kwargs +In previous versions, most of the Guardrails interfaces utilized positional arguments for most parameters. This could be tedious when specifying optional arguments. + +In 0.5.0, for our public interfaces, only required arguments are positional; all optional arguments are keyword only. + +If you previously called you Guard like this: +```py +guard( + openai.chat.completions.create,, + { "topic": "recursion" }, # prompt parameters + 2, # number of reasks + "Write a short statement about ${topic}", # prompt +) +``` + +You will now call it like this: +```py +guard( + openai.chat.completions.create, + prompt_params={ "topic": "recursion" }, + num_reasks=2, + prompt="Write a short statement about ${topic}", +) +``` + +### Validators have moved +We've moved validators to the [Guardrails Hub](https://hub.guardrailsai.com), reducing the core package size for faster installations and smoother workflows. + +Targeted validation: Install only the validators you need, streamlining your project and dependencies. + +New naming: Some validator names changed for clarity and consistency. Head to the hub to find the updated names and grab your validators! + +### AsyncGuard's for Async LLMs +In v0.4.4, we introduced a new `AsyncGuard` for use with asynchronous LLM's. As of 0.5.0, support for async LLM's was removed from the `Guard` class and is now only supported in the `AsyncGuard` class. This should provide better type hinting while developing as well as make the interface simpler and easier to use. + +### Prompt Primitives have moved +In v0.4.5, we introduced `xml` prompt primitives to replace the previous `json` constants. In 0.5.0, the `json` prompt primitives have a different meaning and will likely continue to evolve. If you wish to keep the same constructed prompts as before, you must utilize the new `xml` prompt primitives. + +### Removal of support for older dependency versions +As of 0.5.0, we no longer directly support to following versions of dependencies: + +- Python 3.8 +- Pydantic 1.x +- OpenAI 0.x \ No newline at end of file diff --git a/docs/pydocs/api_reference/actions.py b/docs/pydocs/api_reference/actions.py new file mode 100644 index 000000000..ee79107a0 --- /dev/null +++ b/docs/pydocs/api_reference/actions.py @@ -0,0 +1,60 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from pydoc_markdown.contrib.processors.filter import FilterProcessor +from pydoc_markdown.contrib.renderers.markdown import MarkdownRenderer +from docs.pydocs.helpers import write_to_file + + +exports = [ + "guardrails.actions.reask", + "ReAsk", + "FieldReAsk", + "SkeletonReAsk", + "NonParseableReAsk", + "guardrails.actions.filter", + "Filter", + "apply_filters", + "guardrails.actions.refrain", + "Refrain", + "apply_refrain", +] +export_string = ", ".join([f"'{export}'" for export in exports]) + +write_to_file( + str="# Actions\n\n" + + render_loader( + PythonLoader( + modules=[ + "guardrails.actions.reask", + "guardrails.actions.filter", + "guardrails.actions.refrain", + ], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression=f"name in [{export_string}]", # noqa + skip_empty_modules=True, + ), + renderer=MarkdownRenderer( + # Custom + data_code_block=True, + data_expression_maxlength=250, + header_level_by_type={ + "Class": 2, + "Variable": 2, + }, + # Default + render_module_header=False, + insert_header_anchors=False, + descriptive_class_title=False, + signature_in_header=False, + classdef_code_block=True, + classdef_with_decorators=True, + signature_code_block=True, + signature_with_decorators=True, + render_typehint_in_data_header=True, + ), + ), + filename="docs/api_reference_markdown/actions.md", +) diff --git a/docs/pydocs/api_reference/errors.py b/docs/pydocs/api_reference/errors.py new file mode 100644 index 000000000..48d0b1795 --- /dev/null +++ b/docs/pydocs/api_reference/errors.py @@ -0,0 +1,24 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from pydoc_markdown.contrib.processors.filter import FilterProcessor +from docs.pydocs.helpers import write_to_file + + +exports = ["guardrails.errors.__init__", "guardrails.errors", "ValidationError"] +export_string = ", ".join([f"'{export}'" for export in exports]) + +write_to_file( + str="# Errors\n\n" + + render_loader( + PythonLoader( + modules=["guardrails.errors.__init__"], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression=f"name in [{export_string}]", # noqa + skip_empty_modules=True, + ), + ), + filename="docs/api_reference_markdown/errors.md", +) diff --git a/docs/pydocs/api_reference/formatters.py b/docs/pydocs/api_reference/formatters.py new file mode 100644 index 000000000..fec945a93 --- /dev/null +++ b/docs/pydocs/api_reference/formatters.py @@ -0,0 +1,27 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from docs.pydocs.helpers import write_to_file + + +exports = [ + "guardrails.formatters.json_formatter", + "JsonFormatter", + "guardrails.formatters.base_formatter", + "BaseFormatter", +] +export_string = ", ".join([f"'{export}'" for export in exports]) + +write_to_file( + str="# Formatters\n\n" + + render_loader( + loader=PythonLoader( + modules=[ + "guardrails.formatters.base_formatter", + "guardrails.formatters.json_formatter", + ], + parser=ParserOptions(print_function=False), + ), + ), + filename="docs/api_reference_markdown/formatters.md", +) diff --git a/docs/pydocs/api_reference/generics_and_base_classes.py b/docs/pydocs/api_reference/generics_and_base_classes.py new file mode 100644 index 000000000..6b454fb59 --- /dev/null +++ b/docs/pydocs/api_reference/generics_and_base_classes.py @@ -0,0 +1,27 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from docs.pydocs.helpers import write_to_file + + +exports = [ + "guardrails.classes.generic.arbitrary_model", + "ArbitraryModel", + "guardrails.classes.generic.stack", + "Stack", +] +export_string = ", ".join([f"'{export}'" for export in exports]) + +write_to_file( + str="# Generics And Base Classes\n\n" + + render_loader( + loader=PythonLoader( + modules=[ + "guardrails.classes.generic.arbitrary_model", + "guardrails.classes.generic.stack", + ], + parser=ParserOptions(print_function=False), + ), + ), + filename="docs/api_reference_markdown/generics_and_base_classes.md", +) diff --git a/docs/pydocs/api_reference/guards.py b/docs/pydocs/api_reference/guards.py new file mode 100644 index 000000000..6cdb1a36c --- /dev/null +++ b/docs/pydocs/api_reference/guards.py @@ -0,0 +1,84 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from pydoc_markdown.contrib.processors.filter import FilterProcessor +from docs.pydocs.helpers import write_to_file + + +export_map = { + "guardrails/guard.py": [ + "Guard", + "guardrails.guard", + "guard", + "__init__", + "from_rail", + "from_rail_string", + "from_pydantic", + "from_string", + "configure", + "use", + "use_many", + "__call__", + "parse", + "validate", + "error_spans_in_output", + "json_function_calling_tool", + "to_dict", + "from_dict", + "to_runnable", + ], + "guardrails/async_guard.py": [ + "AsyncGuard", + "guardrails.async_guard", + "async_guard", + "__init__", + "from_rail", + "from_rail_string", + "from_pydantic", + "from_string", + "configure", + "use", + "use_many", + "__call__", + "parse", + "validate", + "error_spans_in_output", + "json_function_calling_tool", + "to_dict", + "from_dict", + "to_runnable", + ], + "guardrails/classes/validation_outcome.py": [ + "guardrails.classes.validation_outcome", + "ValidationOutcome", + "from_guard_history", + ], +} + + +conditionals = [] +for k, v in export_map.items(): + conditionals.append( + f"((name in {v}) if ('{k}' in obj.location.filename) else False)" + ) + +export_string = " or ".join(conditionals) + +write_to_file( + str="# Guards\n\n" + + render_loader( + PythonLoader( + modules=[ + "guardrails.guard", + "guardrails.async_guard", + "guardrails.classes.validation_outcome", + ], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression=f"({export_string})", + skip_empty_modules=True, + ), + ), + filename="docs/api_reference_markdown/guards.md", +) diff --git a/docs/pydocs/api_reference/history.py b/docs/pydocs/api_reference/history.py new file mode 100644 index 000000000..80437f12a --- /dev/null +++ b/docs/pydocs/api_reference/history.py @@ -0,0 +1,22 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from docs.pydocs.helpers import write_to_file + + +write_to_file( + str="# History and Logs\n\n" + + render_loader( + loader=PythonLoader( + modules=[ + "guardrails.classes.history.call", + "guardrails.classes.history.iteration", + "guardrails.classes.history.inputs", + "guardrails.classes.history.outputs", + "guardrails.classes.history.call_inputs", + ], + parser=ParserOptions(print_function=False), + ), + ), + filename="docs/api_reference_markdown/history_and_logs.md", +) diff --git a/docs/pydocs/api_reference/llm_interaction.py b/docs/pydocs/api_reference/llm_interaction.py new file mode 100644 index 000000000..317afb28e --- /dev/null +++ b/docs/pydocs/api_reference/llm_interaction.py @@ -0,0 +1,68 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from pydoc_markdown.contrib.processors.filter import FilterProcessor +from docs.pydocs.helpers import write_to_file + + +export_map = { + "guardrails/prompt/base_prompt.py": [ + "guardrails.prompt.base_prompt", + "BasePrompt", + "__init__", + "format", + "substitute_constants", + "get_prompt_variables", + "escape", + ], + "guardrails/prompt/prompt.py": [ + "guardrails.prompt.prompt", + "Prompt", + "format", + ], + "guardrails/prompt/instructions.py": [ + "guardrails.prompt.instructions", + "Instructions", + "format", + ], + "guardrails/llm_providers.py": [ + "guardrails.llm_providers", + "PromptCallableBase", + "_invoke_llm", + "__call__", + ], + "guardrails/classes/llm/llm_response.py": [ + "guardrails.classes.llm.llm_response", + "LLMResponse", + ], +} + + +conditionals = [] +for k, v in export_map.items(): + conditionals.append( + f"((name in {v}) if ('{k}' in obj.location.filename) else False)" + ) + +export_string = " or ".join(conditionals) + +write_to_file( + str="# Helpers for LLM Interactions\n\n" + + render_loader( + PythonLoader( + modules=[ + "guardrails.prompt.base_prompt", + "guardrails.prompt.prompt", + "guardrails.prompt.instructions", + "guardrails.llm_providers", + "guardrails.classes.llm.llm_response", + ], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression=f"({export_string})", # noqa + skip_empty_modules=True, + ), + ), + filename="docs/api_reference_markdown/llm_interaction.md", +) diff --git a/docs/pydocs/api_reference/types.py b/docs/pydocs/api_reference/types.py new file mode 100644 index 000000000..7ddba4872 --- /dev/null +++ b/docs/pydocs/api_reference/types.py @@ -0,0 +1,73 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from pydoc_markdown.contrib.processors.filter import FilterProcessor +from pydoc_markdown.contrib.renderers.markdown import MarkdownRenderer +from docs.pydocs.helpers import write_to_file + + +exports = [ + "guardrails.types.on_fail", + "guardrails.types.rail", + "OnFailAction", + "RailTypes", + "guardrails.types.inputs", + "guardrails.types.pydantic", + "guardrails.types.validator", + "MessageHistory", + "ModelOrListOfModels", + "ModelOrListOrDict", + "ModelOrModelUnion", + "PydanticValidatorTuple", + "PydanticValidatorSpec", + "UseValidatorSpec", + "UseManyValidatorTuple", + "UseManyValidatorSpec", + "ValidatorMap", +] +export_string = ", ".join([f"'{export}'" for export in exports]) + +write_to_file( + str="# Types\n\n" + + render_loader( + PythonLoader( + modules=[ + "guardrails.types.on_fail", + "guardrails.types.primitives", + "guardrails.types.rail", + "guardrails.types.inputs", + "guardrails.types.pydantic", + "guardrails.types.validator", + ], + parser=ParserOptions( + print_function=False, treat_singleline_comment_blocks_as_docstrings=True + ), + ), + processor=FilterProcessor( + expression=f"name in [{export_string}]", # noqa + skip_empty_modules=True, + ), + renderer=MarkdownRenderer( + # Custom + data_code_block=True, + data_expression_maxlength=250, + header_level_by_type={ + "Class": 2, + "Method": 2, + "Function": 2, + "Variable": 2, + }, + # Default + render_module_header=False, + insert_header_anchors=False, + descriptive_class_title=False, + signature_in_header=False, + classdef_code_block=True, + classdef_with_decorators=True, + signature_code_block=True, + signature_with_decorators=True, + render_typehint_in_data_header=True, + ), + ), + filename="docs/api_reference_markdown/types.md", +) diff --git a/docs/pydocs/api_reference/validation.py b/docs/pydocs/api_reference/validation.py new file mode 100644 index 000000000..31c652c6b --- /dev/null +++ b/docs/pydocs/api_reference/validation.py @@ -0,0 +1,71 @@ +from docspec_python import ParserOptions +from docs.pydocs.pydocs_markdown_impl import render_loader +from pydoc_markdown.contrib.loaders.python import PythonLoader +from pydoc_markdown.contrib.processors.filter import FilterProcessor +from docs.pydocs.helpers import write_to_file + + +# exports = [ +# "docs.pydocs.api_reference.validator", +# "ValidatorReference", +# ] +# export_string = ", ".join([f"'{export}'" for export in exports]) + + +export_map = { + "guardrails/validator_base.py": [ + "guardrails.validator_base", + "Validator", + "__init__", + "chunking_function", + "validate", + "validate_stream", + "with_metadata", + "to_runnable", + "register_validator", + ], + "guardrails/classes/validation/validation_result.py": [ + "guardrails.classes.validation.validation_result", + "ValidationResult", + "PassResult", + "FailResult", + "ErrorSpan", + ], + "guardrails/classes/validation/validator_logs.py": [ + "guardrails.classes.validation.validator_logs", + "ValidatorLogs", + ], + "guardrails/classes/validation/validator_reference.py": [ + "guardrails.classes.validation.validator_reference", + "ValidatorReference", + ], +} + + +conditionals = [] +for k, v in export_map.items(): + conditionals.append( + f"((name in {v}) if ('{k}' in obj.location.filename) else False)" + ) + +export_string = " or ".join(conditionals) + +write_to_file( + str="# Validation\n\n" + + render_loader( + PythonLoader( + modules=[ + "guardrails.validator_base", + "guardrails.classes.validation.validation_result", + "guardrails.classes.validation.validator_logs", + "guardrails.classes.validation.validator_reference", + ], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression=f"({export_string})", + skip_empty_modules=False, + ), + ), + filename="docs/api_reference_markdown/validator.md", +) diff --git a/docs/pydocs/generate_pydocs.py b/docs/pydocs/generate_pydocs.py index a0e428ad1..46e38cfbf 100644 --- a/docs/pydocs/generate_pydocs.py +++ b/docs/pydocs/generate_pydocs.py @@ -1,98 +1,29 @@ -import os -# from pydoc_markdown.interfaces import Context from docspec_python import ParserOptions +from docs.pydocs.helpers import write_to_file from docs.pydocs.pydocs_markdown_impl import render_loader from pydoc_markdown.contrib.loaders.python import PythonLoader -# from guardrails import Rail, Guard, validators, datatypes -# from guardrails.classes.validation_outcome import ValidationOutcome -from pydoc_markdown.contrib.renderers.markdown import MarkdownRenderer -# from guardrails.classes import generic -# from pydocs_to_md import class_to_string, module_to_string -from pydoc_markdown.contrib.processors.filter import FilterProcessor - - -def write_to_file(str, filename): - # if the directory where the filename does not exist, create it - if not os.path.exists(os.path.dirname(filename)): - os.makedirs(os.path.dirname(filename)) - with open(filename, "w") as f: - f.write(str) - f.close() - - -# write_to_file( -# # str=class_to_string(Rail, ignore_prefix_list=["load", "_"]), -# str="# Rail\n\n" + render_loader( -# PythonLoader( -# modules=['guardrails.rail'], -# parser=ParserOptions( -# print_function=False, -# ), -# ), -# processor = FilterProcessor( -# expression="not name.startswith('_') and not name.startswith('load') and default()", -# documented_only=True, - -# ) -# ), -# filename="docs/api_reference_markdown/rail.md", -# ) - - -write_to_file( - str="# Guard\n\n" + render_loader( - PythonLoader( - modules=['guardrails.guard'], - parser=ParserOptions( - print_function=False - ), - ), - processor = FilterProcessor( - expression="name in ['Guard', 'guardrails.guard', 'guard', 'from_rail', 'from_rail_string', 'from_pydantic', 'from_string', 'configure', '__call__', 'parse', 'state']", - skip_empty_modules=True - ) - ), - filename="docs/api_reference_markdown/guard.md", -) +from docs.pydocs.api_reference import actions # noqa +from docs.pydocs.api_reference import errors # noqa +from docs.pydocs.api_reference import formatters # noqa +from docs.pydocs.api_reference import generics_and_base_classes # noqa +from docs.pydocs.api_reference import guards # noqa +from docs.pydocs.api_reference import history # noqa +from docs.pydocs.api_reference import llm_interaction # noqa +from docs.pydocs.api_reference import types # noqa +from docs.pydocs.api_reference import validation # noqa write_to_file( - str="# Validators\n\n" + render_loader( + str="# Validators\n\n" + + render_loader( PythonLoader( - search_path=['validators'], - parser=ParserOptions( - print_function=False - ) + search_path=["validators"], parser=ParserOptions(print_function=False) ) ), filename="docs/hub/api_reference_markdown/validators.md", ) -write_to_file( - # str=class_to_string(ValidationOutcome, ignore_prefix_list=["load", "_"]), - str="# Validation Outcome\n\n" + render_loader( - PythonLoader( - modules=['guardrails.classes.validation_outcome'], - parser=ParserOptions( - print_function=False - ), - ), - processor = FilterProcessor( - documented_only=True, - ), - renderer = MarkdownRenderer( - render_module_header=False, - insert_header_anchors=False, - classdef_code_block=False, - descriptive_class_title=False, - classdef_with_decorators=False, - render_typehint_in_data_header=True, - data_code_block=True, - ) - ), - filename="docs/hub/api_reference_markdown/validation_outcome.md", -) # write_to_file( # str="# Response Structures\n\n" + render_loader( @@ -102,7 +33,7 @@ def write_to_file(str, filename): # processor = FilterProcessor( # expression="""\ # name in \ -# ['guardrails.validator_base', 'ValidationResult', 'PassResult', 'FailResult', 'ValidationError'] \ +# ['guardrails.validator_base', 'ValidationResult', 'PassResult', 'FailResult', 'ValidationError'] \ # noqa # or obj.parent.name in \ # ['ValidationResult', 'PassResult', 'FailResult', 'ValidationError']\ # """, @@ -121,7 +52,6 @@ def write_to_file(str, filename): # ) - # write_to_file( # str="# Schema\n\n" + render_loader(PythonLoader( # modules=['guardrails.schema'], @@ -158,25 +88,6 @@ def write_to_file(str, filename): # filename="docs/api_reference_markdown/datatypes.md", # ) -write_to_file( - str="# History and Logs\n\n" + render_loader( - PythonLoader( - packages=['classes.history'], - parser=ParserOptions( - print_function=False - ), - ), - renderer = MarkdownRenderer( - render_module_header=True, - insert_header_anchors=False, - descriptive_class_title=True, - signature_in_header=True, - classdef_code_block=False, - classdef_with_decorators=False, - ), - ), - filename="docs/api_reference_markdown/history_and_logs.md", -) # write_to_file( # str="# Helper Classes\n\n" + render_loader( diff --git a/docs/pydocs/helpers.py b/docs/pydocs/helpers.py new file mode 100644 index 000000000..23c460234 --- /dev/null +++ b/docs/pydocs/helpers.py @@ -0,0 +1,10 @@ +import os + + +def write_to_file(str, filename): + # if the directory where the filename does not exist, create it + if not os.path.exists(os.path.dirname(filename)): + os.makedirs(os.path.dirname(filename)) + with open(filename, "w") as f: + f.write(str) + f.close() diff --git a/docs/pydocs/pydocs_markdown_impl.py b/docs/pydocs/pydocs_markdown_impl.py index 16272c75a..67187e7a1 100644 --- a/docs/pydocs/pydocs_markdown_impl.py +++ b/docs/pydocs/pydocs_markdown_impl.py @@ -1,21 +1,30 @@ from pydoc_markdown.interfaces import Context -from pydoc_markdown.contrib.renderers.markdown import MarkdownRenderer, MarkdownReferenceResolver +from pydoc_markdown.contrib.renderers.markdown import ( + MarkdownRenderer, + MarkdownReferenceResolver, +) from pydoc_markdown.contrib.processors.filter import FilterProcessor from pydoc_markdown.contrib.processors.google import GoogleProcessor +# from pydoc_markdown.contrib.processors.crossref import CrossrefProcessor -def render_loader(loader, processor = None, renderer = None, context = None): + +def render_loader(loader, processor=None, renderer=None, context=None): if not context: - context = Context(directory='guardrails') + context = Context(directory="guardrails") if not renderer: - renderer = MarkdownRenderer( + new_renderer = MarkdownRenderer( render_module_header=False, insert_header_anchors=False, descriptive_class_title=False, - signature_in_header=True, - classdef_code_block=False, - classdef_with_decorators=False, + signature_in_header=False, + classdef_code_block=True, + classdef_with_decorators=True, + signature_code_block=True, + signature_with_decorators=True, + render_typehint_in_data_header=True, ) + renderer = new_renderer if not processor: processor = FilterProcessor( @@ -24,13 +33,15 @@ def render_loader(loader, processor = None, renderer = None, context = None): google_processor = GoogleProcessor() + # TODO: Add this for api reference + # cross_ref_processor = CrossrefProcessor() + loader.init(context) renderer.init(context) processor.init(context) - modules = list(loader.load()) processor.process(modules=modules, resolver=MarkdownReferenceResolver()) google_processor.process(modules=modules, resolver=MarkdownReferenceResolver()) - return renderer.render_to_string(modules) \ No newline at end of file + return renderer.render_to_string(modules) diff --git a/docs/telemetry.md b/docs/telemetry.md deleted file mode 100644 index 1dcfa2477..000000000 --- a/docs/telemetry.md +++ /dev/null @@ -1,5 +0,0 @@ -1. Go to grafana -2. search for opentelemetry in data sources -3. Create a token, paste in the resulting file to otel-collector-config.yml -4. docker-compose up -f telemetry/docker-compose.yml up -5. run a guard and look for traces \ No newline at end of file diff --git a/docs/the_guard.md b/docs/the_guard.md index 9c1c51c95..ed200c439 100644 --- a/docs/the_guard.md +++ b/docs/the_guard.md @@ -1,6 +1,6 @@ # What is a Guard? -The guard object is the main interface for GuardRails. It is seeded with a RailSpec, and then used to run the GuardRails AI engine. It is the object that accepts changing prompts, wraps LLM prompts, and keeps track of call history. +The guard object is the main interface for GuardRails. It can be used without configuration for string-based LLM apps, and accepts a pydantic object for structured data usecases. The Guard is then used to run the GuardRails AI engine. It is the object that wraps LLM calls, orchestrates validation, and keeps track of call history. ## How it works @@ -11,67 +11,81 @@ The guard object is the main interface for GuardRails. It is seeded with a RailS ## Two main flows ### __call__ -After instantiating a Guard you can call it in order to wrap an LLM with Guardrails and validate the output of that LLM according to the RAIL specification you provided. Calling the guard in this way returns a tuple with the raw output from the LLM first, and the validatd output second. +After initializing a guard, you can invoke it using a model name and messages for your prompt, similarly to how you would invoke a regular call to an LLM SDK. Guardrails will call the LLM and then validate the output against the guardrails you've configured. The output will be returned as a `GuardResponse` object, which contains the raw LLM output, the validated output, and whether or not validation was successful. + ```py -import openai from guardrails import Guard +import os -guard = Guard.from_rail(...) +os.environ["OPENAI_API_KEY"] = [YOUR API KEY] -raw_output, validated_output, *rest = guard( - openai.Completion.create, - engine="text-davinci-003", - max_tokens=1024, - temperature=0.3 +guard = Guard() + +res = guard( + model="gpt-3.5-turbo-instruct", + messages=[{ + "role": "user", + "content": "How do I make a cake?" + }] ) -print(raw_output) -print(validated_output) +print(res.raw_llm_output) +print(res.validated_output) +print(res.validation_passed) ``` ### parse -If you would rather call the LLM yourself, or at least make the first call yourself, you can use `Guard.parse` to apply your RAIL specification to the LLM output as a post process. You can also allow Guardrails to make re-asks to the LLM by specifying the `num_reasks` argument, or keep it purely as a post-processor by setting it to zero. Unlike `__call__`, `Guard.parse` only returns the validated output. +If you would rather call the LLM yourself, or at least make the first call yourself, you can use `Guard.parse` to apply your RAIL specification to the LLM output as a post process. You can also allow Guardrails to make re-asks to the LLM by specifying the `num_reasks` argument, or keep it purely as a post-processor by setting it to zero. `Guard.parse` returns the same fields as `__call__`. -Calling `Guard.parse` with reasks: +Calling `Guard.parse` as a post-processor: ```py import openai from guardrails import Guard -guard = Guard.from_rail(...) +guard = Guard() -output = call_my_llm() +output = openai.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": "How do I make a cake?" + }] +).choices[0].message.content -validated_output = guard.parse( - llm_output=output, - llm_api=openai.Completion.create, - engine="text-davinci-003", - max_tokens=1024, - temperature=0.3, - num_reasks=2 +res = guard.parse( + llm_output=output ) -print(validated_output) +print(res.validated_output) # Validated output ``` -Calling `Guard.parse` as a post-processor: +Calling `Guard.parse` with reasks: ```py import openai from guardrails import Guard -guard = Guard.from_rail(...) +guard = Guard() -output = call_my_llm() +output = openai.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{ + "role": "user", + "content": "How do I make a cake?" + }] +).choices[0].message.content -validated_output = guard.parse( +res = guard.parse( llm_output=output, - num_reasks=0 + model="gpt-3.5-turbo-instruct", + num_reasks=1 ) -print(validated_output) +print(res.validated_output) # Validated output +print(guard.history.last.reasks) # A list of reasks ``` ## Error Handling and Retries -GuardRails currently performs automatic retries with exponential backoff when any of the following errors occur when calling the LLM: +Guardtails currently performs automatic retries with exponential backoff when any of the following errors occur when calling the LLM: - openai.error.APIConnectionError - openai.error.APIError @@ -79,6 +93,7 @@ GuardRails currently performs automatic retries with exponential backoff when an - openai.error.Timeout - openai.error.RateLimitError - openai.error.ServiceUnavailableError +- An incorrect structure was returned from the LLM Note that this list is not exhaustive of the possible errors that could occur. In the event that errors other than these arise during LLM calls, an exception will be raised. The messaging of this exception is intended to help troubleshoot common problems, especially with custom LLM wrappers, as well as communicate the underlying error. This type of exception would look like the following: ```log diff --git a/docs/use_cases/text2sql/text2sql.ipynb b/docs/use_cases/text2sql/text2sql.ipynb index 424ca7818..7cd34acea 100644 --- a/docs/use_cases/text2sql/text2sql.ipynb +++ b/docs/use_cases/text2sql/text2sql.ipynb @@ -63,14 +63,15 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", "import json\n", "\n", "from rich import print\n", "\n", "from guardrails.applications.text2sql import Text2Sql\n", "\n", - "os.environ['OPENAI_API_KEY'] = 'YOUR_API_KEY'" + "# Set your OPENAI_API_KEY as an environment variable\n", + "# import os\n", + "# os.environ['OPENAI_API_KEY'] = \"YOUR_API_KEY\"" ] }, { diff --git a/docusaurus/docusaurus.config.js b/docusaurus/docusaurus.config.js index eca78ee85..7aefbdcb7 100644 --- a/docusaurus/docusaurus.config.js +++ b/docusaurus/docusaurus.config.js @@ -76,15 +76,35 @@ const config = { }, items: [ { - type: "doc", + type: "docSidebar", position: "left", label: "Docs", - docId: "index", + sidebarId: "docs", }, { - type: 'docSidebar', - position: 'left', - sidebarId: 'hubSidebar', - label: 'Hub Docs', + type: "docSidebar", + position: "left", + label: "Concepts", + sidebarId: "concepts" + }, { + type: "docSidebar", + position: "left", + label: "How-to Guides", + sidebarId: "howToGuides" + }, { + type: "docSidebar", + position: "left", + label: "Examples", + sidebarId: "examples" + }, { + type: "docSidebar", + position: "left", + label: "Integrations", + sidebarId: "integrations" + }, { + type: "docSidebar", + position: "left", + label: "API Reference", + sidebarId: "apiReference" } ], }, diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index 87b99057d..84978658b 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -10,6 +10,7 @@ */ // populate examples from examples folder. Only include .mdx and .md files +const { triggerAsyncId } = require("async_hooks"); const fs = require("fs"); // @ts-check @@ -24,105 +25,99 @@ const examples = JSON.parse( const sidebars = { // By default, Docusaurus generates a sidebar from the docs folder structure // tutorialSidebar: [{ type: "autogenerated", dirName: "." }], - docsSidebar: [ + docs: [ + "index", + "getting_started/quickstart", + // "getting_started/why_use", + // "getting_started/ai_validation", + // "getting_started/ml_based", + // "getting_started/structured_data", + "getting_started/guardrails_server", + "getting_started/contributing", + "getting_started/help", + "faq", { - type: "doc", - label: "Introduction", - id: "index", - }, + type: "category", + label: "Migration Guides", + collapsed: false, + items: [ + "migration_guides/0-5-migration", + "migration_guides/0-4-migration", + "migration_guides/0-3-migration", + "migration_guides/0-2-migration", + ] + } + ], + concepts: [ + "concepts/guard", + // "concepts/guardrails", + "concepts/hub", + "concepts/deploying", + "concepts/remote_validation_inference", { - type: "doc", - label: "Getting Started", - id: "guardrails_ai/getting_started", + type: "category", + label: "Streaming", + collapsed: false, + items: [ + "concepts/streaming", + "concepts/async_streaming", + "concepts/streaming_structured_data", + ], }, + "concepts/parallelization", + "concepts/logs", + "concepts/telemetry", + "concepts/error_remediation", + ], + examples: [ + "examples/chatbot", + "examples/summarizer", { - type: "doc", - label: "Installation", - id: "guardrails_ai/installation", + type: "link", + label: "More Examples", + href: "https://github.com/guardrails-ai/guardrails/tree/main/docs/examples", }, - "the_guard", + ], + howToGuides: [ + "how_to_guides/using_llms", + "how_to_guides/enable_streaming", + "how_to_guides/generate_structured_data", + "how_to_guides/deploying_aws", + ], + integrations: [ + // "integrations/azure_openai", + "integrations/langchain", { type: "category", - label: "How-to Guides", - collapsed: true, + label: "Telemetry", + collapsed: false, items: [ - "how_to_guides/llm_api_wrappers", - "how_to_guides/streaming", - "how_to_guides/structured_data_with_guardrails", - "how_to_guides/logs", - "how_to_guides/rail", - "how_to_guides/envvars", - "how_to_guides/telemetry", + { + type: "link", + label: "Arize AI", + href: "https://docs.arize.com/arize/large-language-models/guardrails", + }, + "integrations/telemetry/grafana", ], }, + + // "integrations/openai_functions", + ], + apiReference: [ { type: "category", - label: "API Reference", + label: "Python", collapsed: true, - items: [ + items:[ { type: "autogenerated", dirName: "api_reference_markdown", }, ], }, - examples, - // { - // type: "category", - // label: "Integrations", - // collapsed: true, - // items: [ - // { - // type: "autogenerated", - // dirName: "integrations", - // }, - // ], - // }, - { - type: "category", - label: "Migration Guides", - collapsed: true, - items: [ - "migration_guides/0-4-migration", - "migration_guides/0-3-migration", - "migration_guides/0-2-migration", - ], - }, - { - type: "doc", - id: "faq", - label: "FAQ", - }, - ], - hubSidebar: [ - "hub/introduction", - "hub/getting_started", - { - type: "category", - label: "How-to Guides", - collapsed: true, - items: [{ - type: "autogenerated", - dirName: "hub/how_to_guides", - }] - }, { - type: "category", - label: "Concepts", - collapsed: true, - items: [{ - type: "autogenerated", - dirName: "hub/concepts", - }] - }, { - type: "category", - label: "Reference", - collapsed: true, - items: [{ - type: "autogenerated", - dirName: "hub/api_reference_markdown", - }] - } - ], + "guardrails_server_api", + "cli" + ] }; module.exports = sidebars; diff --git a/guardrails/__init__.py b/guardrails/__init__.py index b1d081fca..f97a38056 100644 --- a/guardrails/__init__.py +++ b/guardrails/__init__.py @@ -5,15 +5,15 @@ from guardrails.llm_providers import PromptCallableBase from guardrails.logging_utils import configure_logging from guardrails.prompt import Instructions, Prompt -from guardrails.rail import Rail from guardrails.utils import constants, docs_utils -from guardrails.validator_base import OnFailAction, Validator, register_validator +from guardrails.types.on_fail import OnFailAction +from guardrails.validator_base import Validator, register_validator +from guardrails.settings import settings __all__ = [ "Guard", "AsyncGuard", - "PromptCallableBase", - "Rail", + "PromptCallableBase", # FIXME: Why is this being exported? "Validator", "OnFailAction", "register_validator", @@ -22,4 +22,5 @@ "configure_logging", "Prompt", "Instructions", + "settings", ] diff --git a/guardrails/actions/__init__.py b/guardrails/actions/__init__.py new file mode 100644 index 000000000..c8aa2b109 --- /dev/null +++ b/guardrails/actions/__init__.py @@ -0,0 +1,16 @@ +from guardrails.actions.filter import Filter, apply_filters + +from guardrails.actions.reask import ReAsk, FieldReAsk, SkeletonReAsk, NonParseableReAsk + +from guardrails.actions.refrain import Refrain, apply_refrain + +__all__ = [ + "Filter", + "apply_filters", + "ReAsk", + "FieldReAsk", + "SkeletonReAsk", + "NonParseableReAsk", + "Refrain", + "apply_refrain", +] diff --git a/guardrails/actions/filter.py b/guardrails/actions/filter.py new file mode 100644 index 000000000..e11bb7d5d --- /dev/null +++ b/guardrails/actions/filter.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, List + + +class Filter: + pass + + +def apply_filters(value: Any) -> Any: + """Recursively filter out any values that are instances of Filter.""" + if isinstance(value, Filter): + pass + elif isinstance(value, List): + # Cleaner syntax but requires two iterations + # filtered_list = list(filter(None, map(apply_filters, value))) + filtered_list = [] + for item in value: + filtered_item = apply_filters(item) + if filtered_item is not None: + filtered_list.append(filtered_item) + + return filtered_list + elif isinstance(value, Dict): + # Cleaner syntax but requires two iterations + # filtered_dict = { + # k: apply_filters(v) + # for k, v in value.items() + # if apply_filters(v) + # } + filtered_dict = {} + for k, v in value.items(): + # Should we omit the key or just the value? + filtered_value = apply_filters(v) + if filtered_value is not None: + filtered_dict[k] = filtered_value + + return filtered_dict + else: + return value diff --git a/guardrails/actions/reask.py b/guardrails/actions/reask.py new file mode 100644 index 000000000..5ed0b8d73 --- /dev/null +++ b/guardrails/actions/reask.py @@ -0,0 +1,651 @@ +from copy import deepcopy +import json +from typing import Any, Dict, List, Optional, Sequence, Tuple, Union + +from guardrails_api_client import Reask as IReask +from guardrails.classes.execution.guard_execution_options import GuardExecutionOptions +from guardrails.classes.output_type import OutputTypes +from guardrails.classes.validation.validation_result import FailResult +from guardrails.prompt.instructions import Instructions +from guardrails.prompt.prompt import Prompt +from guardrails.schema.generator import generate_example +from guardrails.schema.rail_schema import json_schema_to_rail_output +from guardrails.types.validator import ValidatorMap +from guardrails.utils.constants import constants +from guardrails.utils.prompt_utils import prompt_content_for_schema, prompt_uses_xml + + +### Classes/Types ### +class ReAsk(IReask): + """Base class for ReAsk objects. + + Attributes: + incorrect_value (Any): The value that failed validation. + fail_results (List[FailResult]): The results of the failed validations. + """ + + incorrect_value: Any + fail_results: List[FailResult] + + @classmethod + def from_interface(cls, reask: IReask) -> "ReAsk": + fail_results = [] + if reask.fail_results: + fail_results: List[FailResult] = [ + FailResult.from_interface(fail_result) + for fail_result in reask.fail_results + ] + + if reask.additional_properties.get("path"): + return FieldReAsk( + incorrect_value=reask.incorrect_value, + fail_results=fail_results, + path=reask.additional_properties["path"], + ) + + if len(fail_results) == 1: + error_message = fail_results[0].error_message + if error_message == "Output is not parseable as JSON": + return NonParseableReAsk( + incorrect_value=reask.incorrect_value, + fail_results=fail_results, + ) + elif "JSON does not match schema" in error_message: + return SkeletonReAsk( + incorrect_value=reask.incorrect_value, + fail_results=fail_results, + ) + + return cls(incorrect_value=reask.incorrect_value, fail_results=fail_results) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Optional["ReAsk"]: + i_reask = super().from_dict(obj) + if not i_reask: + return None + return cls.from_interface(i_reask) + + +class FieldReAsk(ReAsk): + """An implementation of ReAsk that is used to reask for a specific field. + Inherits from ReAsk. + + Attributes: + path (Optional[List[Any]]): a list of keys that + designated the path to the field that failed validation. + """ + + # FIXME: This shouldn't be optional + # We should be able to assign it on init now + path: Optional[List[Any]] = None + + +class SkeletonReAsk(ReAsk): + """An implementation of ReAsk that is used to reask for structured data + when the response does not match the expected schema. + + Inherits from ReAsk. + """ + + pass + + +class NonParseableReAsk(ReAsk): + """An implementation of ReAsk that is used to reask for structured data + when the response is not parseable as JSON. + + Inherits from ReAsk. + """ + + pass + + +### Internal Helper Methods ### +def get_reask_subschema( + json_schema: Dict[str, Any], + reasks: Optional[List[FieldReAsk]] = None, +) -> Dict[str, Any]: + """Prune schema of any subschemas that are not in `reasks`. + + Return the schema with only the subschemas that are being `reask`ed for and + their parents. If `reasks` is None, return the entire schema. If an + subschema is removed, remove all ancestors that have no children. + + Args: + root: A JSON Schema + reasks: The fields that are to be reasked. + + Returns: + A JSON Schema. + """ + root = deepcopy(json_schema) + + if reasks is None: + return root + + # Find all elements that are to be retained + # NOTE: At this point, in the case of discriminated unions, + # the LLM has already decided which subschema of the union to use. + # This means that we can flatten complex schema compositions, e.g. anyOf's, + # and just build a subschema that represents the resolved schema + # of the LLM response. + # schema_paths_to_retain = [] + # for reask in reasks: + # path = reask.path + # if path is None: + # raise RuntimeError("FieldReAsk path is None") + # schema_path = "$" + # for part in path: + # if isinstance(part, int): + # schema_path += ".items" + # else: + # schema_path += f".properties.{path}" + # schema_paths_to_retain.append(schema_path) + + # # Remove all elements that are not to be retained + # def _prune_schema(schema: Dict[str, Any]) -> None: + # if schema.get("type") == SimpleTypes.ARRAY: + # if schema.children.item not in retain: + # del schema._children["item"] + # else: + # _prune_schema(schema.children.item) + # else: # if isinstance(schema, ObjectType): + # for child_name, child in vars(schema.children).items(): + # if child not in retain: + # del schema._children[child_name] + # else: + # _prune_schema(child) + + # _prune_schema(root) + + # FIXME: PUNT + return root + + +def prune_obj_for_reasking(obj: Any) -> Union[None, Dict, List, ReAsk]: + """After validation, we get a nested dictionary where some keys may be + ReAsk objects. + + This function prunes the validated form of any object that is not a ReAsk object. + It also keeps all of the ancestors of the ReAsk objects. + + Args: + obj: The validated object. + + Returns: + The pruned validated object. + """ + + if isinstance(obj, ReAsk): + return obj + elif isinstance(obj, list): + pruned_list = [] + for item in obj: + pruned_output = prune_obj_for_reasking(item) + if pruned_output is not None: + pruned_list.append(pruned_output) + if len(pruned_list): + return pruned_list + return None + elif isinstance(obj, dict): + pruned_json = {} + for key, value in obj.items(): + if isinstance(value, FieldReAsk): + pruned_json[key] = value + elif isinstance(value, dict): + pruned_output = prune_obj_for_reasking(value) + if pruned_output is not None: + pruned_json[key] = pruned_output + elif isinstance(value, list): + pruned_list = [] + for item in value: + pruned_output = prune_obj_for_reasking(item) + if pruned_output is not None: + pruned_list.append(pruned_output) + if len(pruned_list): + pruned_json[key] = pruned_list + + if len(pruned_json): + return pruned_json + + return None + + +def update_response_by_path(output: dict, path: List[Any], value: Any) -> None: + """Update the output by path. + + Args: + output: The output. + path: The path to the element to be updated. + value: The value to be updated. + """ + for key in path[:-1]: + output = output[key] + output[path[-1]] = value + + +### Guard Execution Methods ### +def introspect( + data: Optional[Union[ReAsk, str, Dict, List]], +) -> Tuple[Sequence[ReAsk], Optional[Union[str, Dict, List]]]: + if isinstance(data, FieldReAsk): + return [data], None + elif isinstance(data, SkeletonReAsk): + return [data], None + elif isinstance(data, NonParseableReAsk): + return [data], None + return gather_reasks(data) + + +def get_reask_setup_for_string( + output_type: OutputTypes, + output_schema: Dict[str, Any], + validation_map: ValidatorMap, + reasks: Sequence[ReAsk], + *, + validation_response: Optional[Union[str, List, Dict, ReAsk]] = None, + prompt_params: Optional[Dict[str, Any]] = None, + exec_options: Optional[GuardExecutionOptions] = None, +) -> Tuple[Dict[str, Any], Prompt, Instructions]: + prompt_params = prompt_params or {} + exec_options = exec_options or GuardExecutionOptions() + + schema_prompt_content = prompt_content_for_schema( + output_type, output_schema, validation_map + ) + xml_output_schema = json_schema_to_rail_output( + json_schema=output_schema, validator_map=validation_map + ) + + reask_prompt_template = None + if exec_options.reask_prompt: + reask_prompt_template = Prompt(exec_options.reask_prompt) + else: + reask_prompt_template = Prompt( + constants["high_level_string_reask_prompt"] + + constants["complete_string_suffix"] + ) + + error_messages = "\n".join( + [ + f"- {fail_result.error_message}" + for reask in reasks + for fail_result in reask.fail_results + ] + ) + + prompt = reask_prompt_template.format( + # FIXME: How do we properly type this? + # Solution will have to come from Runner all the way down to here + previous_response=validation_response.incorrect_value, # type: ignore + error_messages=error_messages, + output_schema=schema_prompt_content, + xml_output_schema=xml_output_schema, + **prompt_params, + ) + + instructions = None + if exec_options.reask_instructions: + instructions = Instructions(exec_options.reask_instructions) + if instructions is None: + instructions = Instructions("You are a helpful assistant.") + instructions = instructions.format( + output_schema=schema_prompt_content, + xml_output_schema=xml_output_schema, + **prompt_params, + ) + + return output_schema, prompt, instructions + + +def get_original_prompt(exec_options: Optional[GuardExecutionOptions] = None) -> str: + exec_options = exec_options or GuardExecutionOptions() + original_msg_history = exec_options.msg_history or [] + msg_history_prompt = next( + ( + h.get("content") + for h in original_msg_history + if isinstance(h, dict) and h.get("role") == "user" + ), + "", + ) + original_prompt = exec_options.prompt or msg_history_prompt or "" + return original_prompt + + +def get_reask_setup_for_json( + output_type: OutputTypes, + output_schema: Dict[str, Any], + validation_map: ValidatorMap, + reasks: Sequence[ReAsk], + *, + parsing_response: Optional[Union[str, List, Dict, ReAsk]] = None, + validation_response: Optional[Union[str, List, Dict, ReAsk]] = None, + use_full_schema: Optional[bool] = False, + prompt_params: Optional[Dict[str, Any]] = None, + exec_options: Optional[GuardExecutionOptions] = None, +) -> Tuple[Dict[str, Any], Prompt, Instructions]: + reask_schema = output_schema + is_skeleton_reask = not any(isinstance(reask, FieldReAsk) for reask in reasks) + is_nonparseable_reask = any( + isinstance(reask, NonParseableReAsk) for reask in reasks + ) + error_messages = {} + prompt_params = prompt_params or {} + exec_options = exec_options or GuardExecutionOptions() + original_prompt = get_original_prompt(exec_options) + use_xml = prompt_uses_xml(original_prompt) + + reask_prompt_template = None + if exec_options.reask_prompt: + reask_prompt_template = Prompt(exec_options.reask_prompt) + + if is_nonparseable_reask: + if reask_prompt_template is None: + suffix = ( + constants["xml_suffix_without_examples"] + if use_xml + else constants["json_suffix_without_examples"] + ) + reask_prompt_template = Prompt( + constants["high_level_json_parsing_reask_prompt"] + suffix + ) + np_reask: NonParseableReAsk = next( + r for r in reasks if isinstance(r, NonParseableReAsk) + ) + # Give the LLM what it gave us that couldn't be parsed as JSON + reask_value = np_reask.incorrect_value + elif is_skeleton_reask: + if reask_prompt_template is None: + reask_prompt = constants["high_level_skeleton_reask_prompt"] + + if use_xml: + reask_prompt = ( + reask_prompt + constants["xml_suffix_with_structure_example"] + ) + else: + reask_prompt = ( + reask_prompt + + constants["error_messages"] + + constants["json_suffix_with_structure_example"] + ) + + reask_prompt_template = Prompt(reask_prompt) + + # Validation hasn't happend yet + # and the problem is with the json the LLM gave us. + # Give it this same json and tell it to fix it. + reask_value = validation_response if use_xml else parsing_response + skeleton_reask: SkeletonReAsk = next( + r for r in reasks if isinstance(r, SkeletonReAsk) + ) + error_messages = skeleton_reask.fail_results[0].error_message + else: + if use_full_schema: + # Give the LLM the full JSON that failed validation + reask_value = validation_response if use_xml else parsing_response + # Don't prune the tree if we're reasking with pydantic model + # (and openai function calling) + else: + # Prune out the individual fields that did not fail validation. + # Only reask for field that did fail. + reask_value = prune_obj_for_reasking(validation_response) + + # Generate a subschema that matches the specific fields we're reasking for. + field_reasks = [r for r in reasks if isinstance(r, FieldReAsk)] + reask_schema = get_reask_subschema(output_schema, field_reasks) + + if reask_prompt_template is None: + suffix = ( + constants["xml_suffix_without_examples"] + if use_xml + else constants["json_suffix_without_examples"] + ) + reask_prompt_template = Prompt( + constants["high_level_json_reask_prompt"] + suffix + ) + + error_messages = { + ".".join(str(p) for p in r.path): "; ".join( # type: ignore + f.error_message for f in r.fail_results + ) + for r in reasks + if isinstance(r, FieldReAsk) + } + + stringified_schema = prompt_content_for_schema( + output_type, reask_schema, validation_map + ) + xml_output_schema = json_schema_to_rail_output( + json_schema=output_schema, validator_map=validation_map + ) + + json_example = json.dumps( + generate_example(reask_schema), + indent=2, + ) + + def reask_decoder(obj: ReAsk): + decoded = {} + for k, v in obj.__dict__.items(): + if k in ["path", "additional_properties"]: + continue + if k == "fail_results": + k = "error_messages" + v = [result.error_message for result in v] + decoded[k] = v + return decoded + + prompt = reask_prompt_template.format( + previous_response=json.dumps( + reask_value, indent=2, default=reask_decoder, ensure_ascii=False + ), + output_schema=stringified_schema, + xml_output_schema=xml_output_schema, + json_example=json_example, + error_messages=json.dumps(error_messages), + **prompt_params, + ) + + instructions = None + if exec_options.reask_instructions: + instructions = Instructions(exec_options.reask_instructions) + else: + instructions_const = ( + constants["high_level_xml_instructions"] + if use_xml + else constants["high_level_json_instructions"] + ) + instructions = Instructions(instructions_const) + instructions = instructions.format(**prompt_params) + + return reask_schema, prompt, instructions + + +def get_reask_setup( + output_type: OutputTypes, + output_schema: Dict[str, Any], + validation_map: ValidatorMap, + reasks: Sequence[ReAsk], + *, + parsing_response: Optional[Union[str, List, Dict, ReAsk]] = None, + validation_response: Optional[Union[str, List, Dict, ReAsk]] = None, + use_full_schema: Optional[bool] = False, + prompt_params: Optional[Dict[str, Any]] = None, + exec_options: Optional[GuardExecutionOptions] = None, +) -> Tuple[Dict[str, Any], Prompt, Instructions]: + prompt_params = prompt_params or {} + exec_options = exec_options or GuardExecutionOptions() + + if output_type == OutputTypes.STRING: + return get_reask_setup_for_string( + output_type=output_type, + output_schema=output_schema, + validation_map=validation_map, + reasks=reasks, + validation_response=validation_response, + prompt_params=prompt_params, + exec_options=exec_options, + ) + return get_reask_setup_for_json( + output_type=output_type, + output_schema=output_schema, + validation_map=validation_map, + reasks=reasks, + parsing_response=parsing_response, + validation_response=validation_response, + use_full_schema=use_full_schema, + prompt_params=prompt_params, + exec_options=exec_options, + ) + + +### Post-Processing Methods ### +def gather_reasks( + validated_output: Optional[Union[ReAsk, str, Dict, List]], +) -> Tuple[List[ReAsk], Optional[Union[str, Dict, List]]]: + """Traverse output and gather all ReAsk objects. + + Args: + validated_output (Union[str, Dict, ReAsk], optional): The output of a model. + Each value can be a ReAsk, a list, a dictionary, or a single value. + + Returns: + A list of ReAsk objects found in the output. + """ + if validated_output is None: + return [], None + if isinstance(validated_output, ReAsk): + return [validated_output], None + if isinstance(validated_output, str): + return [], validated_output + + reasks = [] + + def _gather_reasks_in_dict( + original: Dict, valid_output: Dict, path: Optional[List[Union[str, int]]] = None + ) -> None: + if path is None: + path = [] + for field, value in original.items(): + if isinstance(value, FieldReAsk): + value.path = path + [field] + reasks.append(value) + del valid_output[field] + + if isinstance(value, dict): + _gather_reasks_in_dict(value, valid_output[field], path + [field]) + + if isinstance(value, list): + _gather_reasks_in_list(value, valid_output[field], path + [field]) + return + + def _gather_reasks_in_list( + original: List, valid_output: List, path: Optional[List[Union[str, int]]] = None + ) -> None: + if path is None: + path = [] + for idx, item in enumerate(original): + if isinstance(item, FieldReAsk): + item.path = path + [idx] + reasks.append(item) + del valid_output[idx] + elif isinstance(item, dict): + _gather_reasks_in_dict(item, valid_output[idx], path + [idx]) + elif isinstance(item, list): + _gather_reasks_in_list(item, valid_output[idx], path + [idx]) + return + + if isinstance(validated_output, Dict): + valid_output = deepcopy(validated_output) + _gather_reasks_in_dict(validated_output, valid_output) + return reasks, valid_output + elif isinstance(validated_output, List): + valid_output = deepcopy(validated_output) + _gather_reasks_in_list(validated_output, valid_output) + return reasks, valid_output + return reasks, None + + +def sub_reasks_with_fixed_values(value: Any) -> Any: + """Substitute ReAsk objects with their fixed values recursively. + + Args: + value: Either a list, a dictionary, a ReAsk object or a scalar value. + + Returns: + The value with ReAsk objects replaced with their fixed values. + """ + copy = deepcopy(value) + if isinstance(copy, list): + for index, item in enumerate(copy): + copy[index] = sub_reasks_with_fixed_values(item) + elif isinstance(copy, dict): + for dict_key, dict_value in value.items(): + copy[dict_key] = sub_reasks_with_fixed_values(dict_value) + elif isinstance(copy, FieldReAsk): + fix_value = copy.fail_results[0].fix_value + # TODO handle multiple fail results + # Leave the ReAsk in place if there is no fix value + # This allows us to determine the proper status for the call + copy = fix_value if fix_value is not None else copy + + return copy + + +def merge_reask_output(previous_response, reask_response) -> Dict: + """Merge the reask output into the original output. + + Args: + prev_logs: validation output object from the previous iteration. + current_logs: validation output object from the current iteration. + + Returns: + The merged output. + """ + if isinstance(previous_response, ReAsk): + return reask_response + + # FIXME: Uncommenet when field level reask is fixed + # This used to be necessary for field level reask because + # the schema was pruned to only the properties that failed. + # This caused previous keys that were correct to be pruned during schemafication. + # pruned_reask_json = prune_obj_for_reasking(previous_response) + pruned_reask_json = previous_response + + # Reask output and reask json have the same structure, except that values + # of the reask json are ReAsk objects. We want to replace the ReAsk objects + # with the values from the reask output. + merged_json = deepcopy(previous_response) + + def update_reasked_elements(pruned_reask_json, reask_response_dict): + if isinstance(pruned_reask_json, dict): + for key, value in pruned_reask_json.items(): + if isinstance(value, FieldReAsk): + if value.path is None: + raise RuntimeError( + "FieldReAsk object must have a path attribute." + ) + corrected_value = reask_response_dict.get(key) + update_response_by_path(merged_json, value.path, corrected_value) + else: + update_reasked_elements( + pruned_reask_json[key], reask_response_dict[key] + ) + elif isinstance(pruned_reask_json, list): + for i, item in enumerate(pruned_reask_json): + if isinstance(item, FieldReAsk): + if item.path is None: + raise RuntimeError( + "FieldReAsk object must have a path attribute." + ) + corrected_value = reask_response_dict[i] + update_response_by_path(merged_json, item.path, corrected_value) + else: + update_reasked_elements( + pruned_reask_json[i], reask_response_dict[i] + ) + + update_reasked_elements(pruned_reask_json, reask_response) + + return merged_json diff --git a/guardrails/actions/refrain.py b/guardrails/actions/refrain.py new file mode 100644 index 000000000..a4819cc20 --- /dev/null +++ b/guardrails/actions/refrain.py @@ -0,0 +1,43 @@ +from typing import Any, Dict, List, Union +from guardrails.classes.output_type import OutputTypes +from guardrails.logger import logger + + +class Refrain: + pass + + +def check_for_refrain(value: Union[List, Dict]) -> bool: + if isinstance(value, Refrain): + return True + elif isinstance(value, list): + for item in value: + if check_for_refrain(item): + return True + elif isinstance(value, dict): + for key, child in value.items(): + if check_for_refrain(child): + return True + + return False + + +# Could be a generic instead of Any +def apply_refrain(value: Any, output_type: OutputTypes) -> Any: + """Recursively check for any values that are instances of Refrain. + + If found, return an empty value of the appropriate type. + """ + refrain_value = {} + if output_type == OutputTypes.STRING: + refrain_value = "" + elif output_type == OutputTypes.LIST: + refrain_value = [] + + if check_for_refrain(value): + # If the data contains a `Refain` value, we return an empty + # value. + logger.debug("Refrain detected.") + value = refrain_value + + return value diff --git a/guardrails/api_client.py b/guardrails/api_client.py index 55af0fdaf..dc710c383 100644 --- a/guardrails/api_client.py +++ b/guardrails/api_client.py @@ -1,17 +1,26 @@ import json import os -from typing import Generator, Optional +from typing import Any, Iterable, Optional import requests -from guardrails_api_client import AuthenticatedClient -from guardrails_api_client.api.guard import update_guard, validate -from guardrails_api_client.models import Guard, ValidatePayload, ValidationOutput -from guardrails_api_client.types import UNSET -from httpx import Timeout +from guardrails_api_client.configuration import Configuration +from guardrails_api_client.api_client import ApiClient +from guardrails_api_client.api.guard_api import GuardApi +from guardrails_api_client.api.validate_api import ValidateApi +from guardrails_api_client.models import ( + Guard, + ValidatePayload, + ValidationOutcome as IValidationOutcome, +) + +from guardrails.logger import logger class GuardrailsApiClient: - _client: AuthenticatedClient + _api_client: ApiClient + _guard_api: GuardApi + _validate_api: ValidateApi + timeout: float base_url: str api_key: str @@ -24,15 +33,24 @@ def __init__(self, base_url: Optional[str] = None, api_key: Optional[str] = None self.api_key = ( api_key if api_key is not None else os.environ.get("GUARDRAILS_API_KEY", "") ) - self._client = AuthenticatedClient( - base_url=self.base_url, # type: ignore - follow_redirects=True, # type: ignore - token=self.api_key, - timeout=Timeout(300), # type: ignore + self.timeout = 300 + self._api_client = ApiClient( + configuration=Configuration(api_key=self.api_key, host=self.base_url) ) + self._guard_api = GuardApi(self._api_client) + self._validate_api = ValidateApi(self._api_client) def upsert_guard(self, guard: Guard): - update_guard.sync(guard_name=guard.name, client=self._client, body=guard) + self._guard_api.update_guard( + guard_name=guard.name, body=guard, _request_timeout=self.timeout + ) + + def fetch_guard(self, guard_name: str) -> Optional[Guard]: + try: + return self._guard_api.get_guard(guard_name=guard_name) + except Exception as e: + logger.error(f"Error fetching guard {guard_name}: {e}") + return None def validate( self, @@ -43,12 +61,11 @@ def validate( _openai_api_key = ( openai_api_key if openai_api_key is not None - else os.environ.get("OPENAI_API_KEY", UNSET) + else os.environ.get("OPENAI_API_KEY") ) - return validate.sync( + return self._validate_api.validate( guard_name=guard.name, - client=self._client, - body=payload, + validate_payload=payload, x_openai_api_key=_openai_api_key, ) @@ -57,11 +74,11 @@ def stream_validate( guard: Guard, payload: ValidatePayload, openai_api_key: Optional[str] = None, - ) -> Generator[ValidationOutput, None, None]: + ) -> Iterable[Any]: _openai_api_key = ( openai_api_key if openai_api_key is not None - else os.environ.get("OPENAI_API_KEY", UNSET) + else os.environ.get("OPENAI_API_KEY") ) url = f"{self.base_url}/guards/{guard.name}/validate" @@ -81,4 +98,7 @@ def stream_validate( ) if line: json_output = json.loads(line) - yield ValidationOutput.from_dict(json_output) + yield IValidationOutcome.from_dict(json_output) + + def get_history(self, guard_name: str, call_id: str): + return self._guard_api.get_guard_history(guard_name, call_id) diff --git a/guardrails/applications/text2sql.py b/guardrails/applications/text2sql.py index cf3a91ca7..b2fe86333 100644 --- a/guardrails/applications/text2sql.py +++ b/guardrails/applications/text2sql.py @@ -140,7 +140,7 @@ def _init_guard( rail_spec_str = Template(rail_spec_str).safe_substitute(**rail_params) guard = Guard.from_rail_string(rail_spec_str) - guard.rail.output_schema.reask_prompt_template = reask_prompt + guard._exec_opts.reask_prompt = reask_prompt return guard diff --git a/guardrails/async_guard.py b/guardrails/async_guard.py index 319122e55..d69be04d0 100644 --- a/guardrails/async_guard.py +++ b/guardrails/async_guard.py @@ -1,3 +1,4 @@ +from builtins import id as object_id import contextvars import inspect from typing import ( @@ -6,32 +7,43 @@ Awaitable, Callable, Dict, - Iterable, + Generic, List, Optional, + Sequence, Union, cast, ) -from guardrails_api_client.models import ValidatePayload, ValidationOutput +from guardrails_api_client.models import ( + ValidatePayload, + ValidationOutcome as IValidationOutcome, +) from guardrails import Guard from guardrails.classes import OT, ValidationOutcome from guardrails.classes.history import Call from guardrails.classes.history.call_inputs import CallInputs +from guardrails.classes.output_type import OutputTypes +from guardrails.classes.schema.processed_schema import ProcessedSchema from guardrails.llm_providers import get_async_llm_ask, model_is_supported_server_side from guardrails.logger import set_scope from guardrails.run import AsyncRunner, AsyncStreamRunner from guardrails.stores.context import ( + Tracer, get_call_kwarg, set_call_kwargs, set_tracer, set_tracer_context, ) +from guardrails.types.pydantic import ModelOrListOfModels +from guardrails.types.validator import UseManyValidatorSpec, UseValidatorSpec +from guardrails.utils.validator_utils import verify_metadata_requirements +from guardrails.validator_base import Validator -class AsyncGuard(Guard): - """The Guard class. +class AsyncGuard(Guard, Generic[OT]): + """The AsyncGuard class. This class one of the main entry point for using Guardrails. It is initialized from one of the following class methods: @@ -47,46 +59,151 @@ class AsyncGuard(Guard): the LLM and the validated output stream. """ - async def __call__( + @classmethod + def _from_rail_schema( + cls, + schema: ProcessedSchema, + rail: str, + *, + num_reasks: Optional[int] = None, + tracer: Optional[Tracer] = None, + name: Optional[str] = None, + description: Optional[str] = None, + ): + guard = super()._from_rail_schema( + schema, + rail, + num_reasks=num_reasks, + tracer=tracer, + name=name, + description=description, + ) + if schema.output_type == OutputTypes.STRING: + return cast(AsyncGuard[str], guard) + elif schema.output_type == OutputTypes.LIST: + return cast(AsyncGuard[List], guard) + else: + return cast(AsyncGuard[Dict], guard) + + @classmethod + def from_pydantic( + cls, + output_class: ModelOrListOfModels, + *, + prompt: Optional[str] = None, # deprecate this too + instructions: Optional[str] = None, # deprecate this too + num_reasks: Optional[int] = None, + reask_prompt: Optional[str] = None, # deprecate this too + reask_instructions: Optional[str] = None, # deprecate this too + tracer: Optional[Tracer] = None, + name: Optional[str] = None, + description: Optional[str] = None, + ): + guard = super().from_pydantic( + output_class, + prompt=prompt, + instructions=instructions, + num_reasks=num_reasks, + reask_prompt=reask_prompt, + reask_instructions=reask_instructions, + tracer=tracer, + name=name, + description=description, + ) + if guard._output_type == OutputTypes.LIST: + return cast(AsyncGuard[List], guard) + else: + return cast(AsyncGuard[Dict], guard) + + @classmethod + def from_string( + cls, + validators: Sequence[Validator], + *, + string_description: Optional[str] = None, + prompt: Optional[str] = None, # deprecate this too + instructions: Optional[str] = None, # deprecate this too + reask_prompt: Optional[str] = None, # deprecate this too + reask_instructions: Optional[str] = None, # deprecate this too + num_reasks: Optional[int] = None, + tracer: Optional[Tracer] = None, + name: Optional[str] = None, + description: Optional[str] = None, + ): + guard = super().from_string( + validators, + string_description=string_description, + prompt=prompt, + instructions=instructions, + reask_prompt=reask_prompt, + reask_instructions=reask_instructions, + num_reasks=num_reasks, + tracer=tracer, + name=name, + description=description, + ) + return cast(AsyncGuard[str], guard) + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional["AsyncGuard"]: + guard = super().from_dict(obj) + return cast(AsyncGuard, guard) + + def use( + self, + validator: UseValidatorSpec, + *args, + on: str = "output", + **kwargs, + ) -> "AsyncGuard": + guard = super().use(validator, *args, on=on, **kwargs) + return cast(AsyncGuard, guard) + + def use_many( self, - llm_api: Union[Callable, Callable[[Any], Awaitable[Any]]], + *validators: UseManyValidatorSpec, + on: str = "output", + ) -> "AsyncGuard": + guard = super().use_many(*validators, on=on) # type: ignore + return cast(AsyncGuard, guard) + + async def _execute( + self, + *args, + llm_api: Optional[Callable[..., Awaitable[Any]]] = None, + llm_output: Optional[str] = None, prompt_params: Optional[Dict] = None, num_reasks: Optional[int] = None, prompt: Optional[str] = None, instructions: Optional[str] = None, msg_history: Optional[List[Dict]] = None, - metadata: Optional[Dict] = None, + metadata: Optional[Dict], full_schema_reask: Optional[bool] = None, - *args, **kwargs, ) -> Union[ - Union[ValidationOutcome[OT], Iterable[ValidationOutcome[OT]]], + ValidationOutcome[OT], Awaitable[ValidationOutcome[OT]], + AsyncIterable[ValidationOutcome[OT]], ]: - """Call the LLM and validate the output. Pass an async LLM API to - return a coroutine. - - Args: - llm_api: The LLM API to call - (e.g. openai.Completion.create or openai.Completion.acreate) - prompt_params: The parameters to pass to the prompt.format() method. - num_reasks: The max times to re-ask the LLM for invalid output. - prompt: The prompt to use for the LLM. - instructions: Instructions for chat models. - msg_history: The message history to pass to the LLM. - metadata: Metadata to pass to the validators. - full_schema_reask: When reasking, whether to regenerate the full schema - or just the incorrect values. - Defaults to `True` if a base model is provided, - `False` otherwise. - - Returns: - The raw text output from the LLM and the validated output. - """ + self._fill_validator_map() + self._fill_validators() + metadata = metadata or {} + if not llm_output and llm_api and not (prompt or msg_history): + raise RuntimeError( + "'prompt' or 'msg_history' must be provided in order to call an LLM!" + ) + # check if validator requirements are fulfilled + missing_keys = verify_metadata_requirements(metadata, self._validators) + if missing_keys: + raise ValueError( + f"Missing required metadata keys: {', '.join(missing_keys)}" + ) - async def __call( - self, - llm_api: Union[Callable, Callable[[Any], Awaitable[Any]]], + async def __exec( + self: AsyncGuard, + *args, + llm_api: Optional[Callable[..., Awaitable[Any]]], + llm_output: Optional[str] = None, prompt_params: Optional[Dict] = None, num_reasks: Optional[int] = None, prompt: Optional[str] = None, @@ -94,39 +211,43 @@ async def __call( msg_history: Optional[List[Dict]] = None, metadata: Optional[Dict] = None, full_schema_reask: Optional[bool] = None, - *args, **kwargs, - ): - llm_api_str = "" - if llm_api: - llm_api_module_name = ( - llm_api.__module__ if hasattr(llm_api, "__module__") else "" - ) - llm_api_name = ( - llm_api.__name__ - if hasattr(llm_api, "__name__") - else type(llm_api).__name__ - ) - llm_api_str = f"{llm_api_module_name}.{llm_api_name}" - if metadata is None: - metadata = {} + ) -> Union[ + ValidationOutcome[OT], + Awaitable[ValidationOutcome[OT]], + AsyncIterable[ValidationOutcome[OT]], + ]: + prompt_params = prompt_params or {} + metadata = metadata or {} if full_schema_reask is None: - full_schema_reask = self.base_model is not None - if prompt_params is None: - prompt_params = {} + full_schema_reask = self._base_model is not None - if not self._disable_tracer: + if self._allow_metrics_collection: + llm_api_str = "" + if llm_api: + llm_api_module_name = ( + llm_api.__module__ if hasattr(llm_api, "__module__") else "" + ) + llm_api_name = ( + llm_api.__name__ + if hasattr(llm_api, "__name__") + else type(llm_api).__name__ + ) + llm_api_str = f"{llm_api_module_name}.{llm_api_name}" # Create a new span for this guard call self._hub_telemetry.create_new_span( span_name="/guard_call", attributes=[ - ("guard_id", self._guard_id), + ("guard_id", self.id), ("user_id", self._user_id), ("llm_api", llm_api_str), - ("custom_reask_prompt", self.reask_prompt is not None), + ( + "custom_reask_prompt", + self._exec_opts.reask_prompt is not None, + ), ( "custom_reask_instructions", - self.reask_instructions is not None, + self._exec_opts.reask_instructions is not None, ), ], is_parent=True, # It will have children @@ -137,51 +258,52 @@ async def __call( set_tracer(self._tracer) set_tracer_context(self._tracer_context) - self.configure(num_reasks) - if self.num_reasks is None: + self._set_num_reasks(num_reasks=num_reasks) + if self._num_reasks is None: raise RuntimeError( "`num_reasks` is `None` after calling `configure()`. " "This should never happen." ) - input_prompt = prompt or (self.prompt._source if self.prompt else None) - input_instructions = instructions or ( - self.instructions._source if self.instructions else None - ) + input_prompt = prompt or self._exec_opts.prompt + input_instructions = instructions or self._exec_opts.instructions call_inputs = CallInputs( llm_api=llm_api, prompt=input_prompt, instructions=input_instructions, msg_history=msg_history, prompt_params=prompt_params, - num_reasks=self.num_reasks, + num_reasks=self._num_reasks, metadata=metadata, full_schema_reask=full_schema_reask, args=list(args), kwargs=kwargs, - stream=kwargs.get("stream"), ) - call_log = Call(inputs=call_inputs) - set_scope(str(id(call_log))) - self.history.push(call_log) if self._api_client is not None and model_is_supported_server_side( llm_api, *args, **kwargs ): result = self._call_server( + llm_output=llm_output, llm_api=llm_api, - num_reasks=self.num_reasks, + num_reasks=self._num_reasks, prompt_params=prompt_params, + metadata=metadata, full_schema_reask=full_schema_reask, - call_log=call_log, *args, **kwargs, ) + + # If the LLM API is async, return a coroutine else: - result = self._call_async( - llm_api, + call_log = Call(inputs=call_inputs) + set_scope(str(object_id(call_log))) + self.history.push(call_log) + result = await self._exec( + llm_api=llm_api, + llm_output=llm_output, prompt_params=prompt_params, - num_reasks=self.num_reasks, + num_reasks=self._num_reasks, prompt=prompt, instructions=instructions, msg_history=msg_history, @@ -194,38 +316,45 @@ async def __call( if inspect.isawaitable(result): return await result - return result + # TODO: Fix types once async streaming is implemented on server + return result # type: ignore guard_context = contextvars.Context() return await guard_context.run( - __call, + __exec, self, - llm_api, - prompt_params, - num_reasks, - prompt, - instructions, - msg_history, - metadata, - full_schema_reask, + llm_api=llm_api, + llm_output=llm_output, + prompt_params=prompt_params, + num_reasks=num_reasks, + prompt=prompt, + instructions=instructions, + msg_history=msg_history, + metadata=metadata, + full_schema_reask=full_schema_reask, *args, **kwargs, ) - async def _call_async( + async def _exec( self, - llm_api: Callable[[Any], Awaitable[Any]], - prompt_params: Dict, - num_reasks: int, + *args, + llm_api: Optional[Callable[[Any], Awaitable[Any]]], + llm_output: Optional[str] = None, + call_log: Call, + prompt_params: Dict, # Should be defined at this point + num_reasks: int = 0, # Should be defined at this point + metadata: Dict, # Should be defined at this point + full_schema_reask: bool = False, # Should be defined at this point prompt: Optional[str], instructions: Optional[str], msg_history: Optional[List[Dict]], - metadata: Dict, - full_schema_reask: bool, - call_log: Call, - *args, **kwargs, - ) -> Union[ValidationOutcome[OT], AsyncIterable[ValidationOutcome[OT]]]: + ) -> Union[ + ValidationOutcome[OT], + Awaitable[ValidationOutcome[OT]], + AsyncIterable[ValidationOutcome[OT]], + ]: """Call the LLM asynchronously and validate the output. Args: @@ -244,290 +373,219 @@ async def _call_async( Returns: The raw text output from the LLM and the validated output. """ - instructions_obj = instructions or self.rail.instructions - prompt_obj = prompt or self.rail.prompt - msg_history_obj = msg_history or [] - if prompt_obj is None: - if msg_history_obj is not None and not len(msg_history_obj): - raise RuntimeError( - "You must provide a prompt if msg_history is empty. " - "Alternatively, you can provide a prompt in the RAIL spec." - ) + api = get_async_llm_ask(llm_api, *args, **kwargs) # type: ignore if kwargs.get("stream", False): runner = AsyncStreamRunner( - instructions=instructions_obj, - prompt=prompt_obj, - msg_history=msg_history_obj, - api=get_async_llm_ask(llm_api, *args, **kwargs), - prompt_schema=self.rail.prompt_schema, - instructions_schema=self.rail.instructions_schema, - msg_history_schema=self.rail.msg_history_schema, - output_schema=self.rail.output_schema, + output_type=self._output_type, + output_schema=self.output_schema.to_dict(), num_reasks=num_reasks, + validation_map=self._validator_map, + prompt=prompt, + instructions=instructions, + msg_history=msg_history, + api=api, metadata=metadata, - base_model=self.base_model, + output=llm_output, + base_model=self._base_model, full_schema_reask=full_schema_reask, - disable_tracer=self._disable_tracer, + disable_tracer=(not self._allow_metrics_collection), + exec_options=self._exec_opts, ) # Here we have an async generator async_generator = runner.async_run( call_log=call_log, prompt_params=prompt_params ) return async_generator - else: runner = AsyncRunner( - instructions=instructions_obj, - prompt=prompt_obj, - msg_history=msg_history_obj, - api=get_async_llm_ask(llm_api, *args, **kwargs), - prompt_schema=self.rail.prompt_schema, - instructions_schema=self.rail.instructions_schema, - msg_history_schema=self.rail.msg_history_schema, - output_schema=self.rail.output_schema, + output_type=self._output_type, + output_schema=self.output_schema.to_dict(), num_reasks=num_reasks, + validation_map=self._validator_map, + prompt=prompt, + instructions=instructions, + msg_history=msg_history, + api=api, metadata=metadata, - base_model=self.base_model, + output=llm_output, + base_model=self._base_model, full_schema_reask=full_schema_reask, - disable_tracer=self._disable_tracer, + disable_tracer=(not self._allow_metrics_collection), + exec_options=self._exec_opts, ) + # Why are we using a different method here instead of just overriding? call = await runner.async_run( call_log=call_log, prompt_params=prompt_params ) return ValidationOutcome[OT].from_guard_history(call) - async def parse( + async def __call__( self, - llm_output: str, - metadata: Optional[Dict] = None, - llm_api: Optional[Callable] = None, - num_reasks: Optional[int] = None, + llm_api: Optional[Callable[..., Awaitable[Any]]] = None, + *args, prompt_params: Optional[Dict] = None, + num_reasks: Optional[int] = 1, + prompt: Optional[str] = None, + instructions: Optional[str] = None, + msg_history: Optional[List[Dict]] = None, + metadata: Optional[Dict] = None, full_schema_reask: Optional[bool] = None, - *args, **kwargs, - ) -> Union[ValidationOutcome[OT], Awaitable[ValidationOutcome[OT]]]: - """Alternate flow to using Guard where the llm_output is known. + ) -> Union[ + ValidationOutcome[OT], + Awaitable[ValidationOutcome[OT]], + AsyncIterable[ValidationOutcome[OT]], + ]: + """Call the LLM and validate the output. Pass an async LLM API to + return a coroutine. Args: - llm_output: The output being parsed and validated. - metadata: Metadata to pass to the validators. llm_api: The LLM API to call - (e.g. openai.Completion.create or openai.Completion.acreate) - num_reasks: The max times to re-ask the LLM for invalid output. + (e.g. openai.completions.create or openai.chat.completions.create) prompt_params: The parameters to pass to the prompt.format() method. + num_reasks: The max times to re-ask the LLM for invalid output. + prompt: The prompt to use for the LLM. + instructions: Instructions for chat models. + msg_history: The message history to pass to the LLM. + metadata: Metadata to pass to the validators. full_schema_reask: When reasking, whether to regenerate the full schema or just the incorrect values. + Defaults to `True` if a base model is provided, + `False` otherwise. Returns: - The validated response. This is either a string or a dictionary, - determined by the object schema defined in the RAILspec. + The raw text output from the LLM and the validated output. """ - async def __parse( - self, - llm_output: str, - metadata: Optional[Dict] = None, - llm_api: Optional[Callable] = None, - num_reasks: Optional[int] = None, - prompt_params: Optional[Dict] = None, - full_schema_reask: Optional[bool] = None, - *args, - **kwargs, - ): - llm_api_str = "" - if llm_api: - llm_api_module_name = ( - llm_api.__module__ if hasattr(llm_api, "__module__") else "" - ) - llm_api_name = ( - llm_api.__name__ - if hasattr(llm_api, "__name__") - else type(llm_api).__name__ - ) - llm_api_str = f"{llm_api_module_name}.{llm_api_name}" - final_num_reasks = ( - num_reasks if num_reasks is not None else 0 if llm_api is None else None - ) - - if not self._disable_tracer: - self._hub_telemetry.create_new_span( - span_name="/guard_parse", - attributes=[ - ("guard_id", self._guard_id), - ("user_id", self._user_id), - ("llm_api", llm_api_str), - ("custom_reask_prompt", self.reask_prompt is not None), - ( - "custom_reask_instructions", - self.reask_instructions is not None, - ), - ], - is_parent=True, # It will have children - has_parent=False, # Has no parents - ) + instructions = instructions or self._exec_opts.instructions + prompt = prompt or self._exec_opts.prompt + msg_history = msg_history or kwargs.pop("messages", None) or [] - self.configure(final_num_reasks) - if self.num_reasks is None: + if prompt is None: + if msg_history is not None and not len(msg_history): raise RuntimeError( - "`num_reasks` is `None` after calling `configure()`. " - "This should never happen." - ) - if full_schema_reask is None: - full_schema_reask = self.base_model is not None - metadata = metadata or {} - prompt_params = prompt_params or {} - - set_call_kwargs(kwargs) - set_tracer(self._tracer) - set_tracer_context(self._tracer_context) - - input_prompt = self.prompt._source if self.prompt else None - input_instructions = ( - self.instructions._source if self.instructions else None - ) - call_inputs = CallInputs( - llm_api=llm_api, - llm_output=llm_output, - prompt=input_prompt, - instructions=input_instructions, - prompt_params=prompt_params, - num_reasks=self.num_reasks, - metadata=metadata, - full_schema_reask=full_schema_reask, - args=list(args), - kwargs=kwargs, - stream=kwargs.get("stream"), - ) - call_log = Call(inputs=call_inputs) - set_scope(str(id(call_log))) - self.history.push(call_log) - - if self._api_client is not None and model_is_supported_server_side( - llm_api, *args, **kwargs - ): - return self._call_server( - llm_output=llm_output, - llm_api=llm_api, - num_reasks=self.num_reasks, - prompt_params=prompt_params, - full_schema_reask=full_schema_reask, - call_log=call_log, - *args, - **kwargs, + "You must provide a prompt if msg_history is empty. " + "Alternatively, you can provide a prompt in the Schema constructor." ) - return await self._async_parse( - llm_output, - metadata, - llm_api=llm_api, - num_reasks=self.num_reasks, - prompt_params=prompt_params, - full_schema_reask=full_schema_reask, - call_log=call_log, - *args, - **kwargs, - ) - - guard_context = contextvars.Context() - return await guard_context.run( - __parse, - self, - llm_output, - metadata, - llm_api, - num_reasks, - prompt_params, - full_schema_reask, + return await self._execute( *args, + llm_api=llm_api, + prompt_params=prompt_params, + num_reasks=num_reasks, + prompt=prompt, + instructions=instructions, + msg_history=msg_history, + metadata=metadata, + full_schema_reask=full_schema_reask, **kwargs, ) - async def _async_parse( + async def parse( self, llm_output: str, - metadata: Dict, - llm_api: Optional[Callable[[Any], Awaitable[Any]]], - num_reasks: int, - prompt_params: Dict, - full_schema_reask: bool, - call_log: Call, *args, + metadata: Optional[Dict] = None, + llm_api: Optional[Callable[..., Awaitable[Any]]] = None, + num_reasks: Optional[int] = None, + prompt_params: Optional[Dict] = None, + full_schema_reask: Optional[bool] = None, **kwargs, - ) -> ValidationOutcome[OT]: - """Alternate flow to using Guard where the llm_output is known. + ) -> Awaitable[ValidationOutcome[OT]]: + """Alternate flow to using AsyncGuard where the llm_output is known. Args: - llm_output: The output from the LLM. - llm_api: The LLM API to use to re-ask the LLM. + llm_output: The output being parsed and validated. + metadata: Metadata to pass to the validators. + llm_api: The LLM API to call + (e.g. openai.completions.create or openai.Completion.acreate) num_reasks: The max times to re-ask the LLM for invalid output. + prompt_params: The parameters to pass to the prompt.format() method. + full_schema_reask: When reasking, whether to regenerate the full schema + or just the incorrect values. Returns: - The validated response. + The validated response. This is either a string or a dictionary, + determined by the object schema defined in the RAILspec. """ - runner = AsyncRunner( - instructions=kwargs.pop("instructions", None), - prompt=kwargs.pop("prompt", None), - msg_history=kwargs.pop("msg_history", None), - api=get_async_llm_ask(llm_api, *args, **kwargs) if llm_api else None, - prompt_schema=self.rail.prompt_schema, - instructions_schema=self.rail.instructions_schema, - msg_history_schema=self.rail.msg_history_schema, - output_schema=self.rail.output_schema, - num_reasks=num_reasks, + + final_num_reasks = ( + num_reasks + if num_reasks is not None + else self._num_reasks + if self._num_reasks is not None + else 0 + if llm_api is None + else 1 + ) + default_prompt = self._exec_opts.prompt if llm_api is not None else None + prompt = kwargs.pop("prompt", default_prompt) + + default_instructions = self._exec_opts.instructions if llm_api else None + instructions = kwargs.pop("instructions", default_instructions) + + default_msg_history = self._exec_opts.msg_history if llm_api else None + msg_history = kwargs.pop("msg_history", default_msg_history) + + return await self._execute( # type: ignore + *args, + llm_output=llm_output, + llm_api=llm_api, + prompt_params=prompt_params, + num_reasks=final_num_reasks, + prompt=prompt, + instructions=instructions, + msg_history=msg_history, metadata=metadata, - output=llm_output, - base_model=self.base_model, full_schema_reask=full_schema_reask, - disable_tracer=self._disable_tracer, + **kwargs, ) - call = await runner.async_run(call_log=call_log, prompt_params=prompt_params) - - return ValidationOutcome[OT].from_guard_history(call) async def _stream_server_call( - self, - *, - payload: Dict[str, Any], - llm_output: Optional[str] = None, - num_reasks: Optional[int] = None, - prompt_params: Optional[Dict] = None, - metadata: Optional[Dict] = {}, - full_schema_reask: Optional[bool] = True, - call_log: Optional[Call], + self, *, payload: Dict[str, Any] ) -> AsyncIterable[ValidationOutcome[OT]]: # TODO: Once server side supports async streaming, this function will need to # yield async generators, not generators if self._api_client: - validation_output: Optional[ValidationOutput] = None + validation_output: Optional[IValidationOutcome] = None response = self._api_client.stream_validate( guard=self, # type: ignore - payload=ValidatePayload.from_dict(payload), + payload=ValidatePayload.from_dict(payload), # type: ignore openai_api_key=get_call_kwarg("api_key"), ) for fragment in response: validation_output = fragment - if not validation_output: + if validation_output is None: yield ValidationOutcome[OT]( + call_id="0", # type: ignore raw_llm_output=None, validated_output=None, validation_passed=False, error="The response from the server was empty!", ) - yield ValidationOutcome[OT]( - raw_llm_output=validation_output.raw_llm_response, # type: ignore - validated_output=cast(OT, validation_output.validated_output), - validation_passed=validation_output.result, - ) + else: + validated_output = ( + cast(OT, validation_output.validated_output.actual_instance) + if validation_output.validated_output + else None + ) + yield ValidationOutcome[OT]( + call_id=validation_output.call_id, # type: ignore + raw_llm_output=validation_output.raw_llm_output, # type: ignore + validated_output=validated_output, + validation_passed=(validation_output.validation_passed is True), + ) if validation_output: - self._construct_history_from_server_response( - validation_output=validation_output, - llm_output=llm_output, - num_reasks=num_reasks, - prompt_params=prompt_params, - metadata=metadata, - full_schema_reask=full_schema_reask, - call_log=call_log, + guard_history = self._api_client.get_history( + self.name, validation_output.call_id + ) + self.history.extend( + [Call.from_interface(call) for call in guard_history] ) else: - raise ValueError("Guard does not have an api client!") + raise ValueError("AsyncGuard does not have an api client!") + + async def validate( + self, llm_output: str, *args, **kwargs + ) -> Awaitable[ValidationOutcome[OT]]: + return await self.parse(llm_output=llm_output, *args, **kwargs) diff --git a/guardrails/call_tracing/__init__.py b/guardrails/call_tracing/__init__.py new file mode 100644 index 000000000..cfc312cc5 --- /dev/null +++ b/guardrails/call_tracing/__init__.py @@ -0,0 +1,12 @@ +"""For tracing (logging) and reporting the timing of Guard and Validator calls. + +sqlite_trace_handler defines most of the actual implementation methods. +trace_handler provides the singleton that's used for fast global access +across threads. tracer_mixin defines the interface and can act as a +noop. trace_entry is just a helpful dataclass. +""" + +from guardrails.call_tracing.trace_entry import GuardTraceEntry +from guardrails.call_tracing.trace_handler import TraceHandler + +__all__ = ["GuardTraceEntry", "TraceHandler"] diff --git a/guardrails/call_tracing/sqlite_trace_handler.py b/guardrails/call_tracing/sqlite_trace_handler.py new file mode 100644 index 000000000..1d555d6fd --- /dev/null +++ b/guardrails/call_tracing/sqlite_trace_handler.py @@ -0,0 +1,235 @@ +"""sqlite_trace_handler.py. + +This is the metaphorical bread and butter of our tracing implementation, +or at least the butter. It wraps a SQLite database and configures it to +be 'agreeable' in multithreaded situations. Normally, when sharing +across threads and instances one should consider using a larger database +solution like Postgres, but in this case we only care about _supporting_ +writing from multiple places. We don't expect it will be the norm. We +care about (1) not negatively impacting performance, (2) not crashing +when used in unusual ways, and (3) not losing data when possible. + +The happy path should be reasonably performant. The unhappy path should +not crash. + +The other part of the multithreaded support comes from the public +trace_handler, which uses a singleton pattern to only have a single +instance of the database per-thread. If we _do_ somehow end up shared +across threads, the journaling settings and writeahead should protect us +from odd behavior. +""" + +import datetime +import os +import sqlite3 +import time +from dataclasses import asdict +from typing import Iterator + +from guardrails.call_tracing.trace_entry import GuardTraceEntry +from guardrails.call_tracing.tracer_mixin import TracerMixin +from guardrails.classes.validation.validator_logs import ValidatorLogs +from guardrails.utils.casting_utils import to_string + + +LOG_RETENTION_LIMIT = 100000 +TIME_BETWEEN_CLEANUPS = 10.0 # Seconds + + +# These adapters make it more convenient to add data into our log DB: +# Handle timestamp -> sqlite map: +def adapt_datetime(val): + """Adapt datetime.datetime to Unix timestamp.""" + # return val.isoformat() # If we want to go to datetime/isoformat... + return int(val.timestamp()) + + +sqlite3.register_adapter(datetime.datetime, adapt_datetime) + + +def convert_timestamp(val): + """Convert Unix epoch timestamp to datetime.datetime object.""" + # To go to datetime.datetime: + # return datetime.datetime.fromisoformat(val.decode()) + return datetime.datetime.fromtimestamp(int(val)) + + +sqlite3.register_converter("timestamp", convert_timestamp) + + +# This structured handler shouldn't be used directly, since it's touching a SQLite db. +# Instead, use the singleton or the async singleton. +class SQLiteTraceHandler(TracerMixin): + CREATE_COMMAND = """ + CREATE TABLE IF NOT EXISTS guard_logs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guard_name TEXT, + start_time REAL, + end_time REAL, + prevalidate_text TEXT, + postvalidate_text TEXT, + exception_message TEXT + ); + """ + INSERT_COMMAND = """ + INSERT INTO guard_logs ( + guard_name, start_time, end_time, prevalidate_text, postvalidate_text, + exception_message + ) VALUES ( + :guard_name, :start_time, :end_time, :prevalidate_text, :postvalidate_text, + :exception_message + ); + """ + + def __init__(self, log_path: os.PathLike, read_mode: bool): + self._log_path = log_path # Read-only value. + self.last_cleanup = time.time() + self.readonly = read_mode + if read_mode: + self.db = SQLiteTraceHandler._get_read_connection(log_path) + else: + self.db = SQLiteTraceHandler._get_write_connection(log_path) + + @property + def log_path(self): + return self._log_path + + @classmethod + def _get_write_connection(cls, log_path: os.PathLike) -> sqlite3.Connection: + try: + db = sqlite3.connect( + log_path, + isolation_level=None, + check_same_thread=False, + ) + db.execute("PRAGMA journal_mode = wal") + db.execute("PRAGMA synchronous = OFF") + # isolation_level = None and pragma WAL means we can READ from the DB + # while threads using it are writing. Synchronous off puts us on the + # highway to the danger zone, depending on how willing we are to lose log + # messages in the event of a guard crash. + except sqlite3.OperationalError as e: + # logging.exception("Unable to connect to guard log handler.") + raise e + with db: + db.execute(SQLiteTraceHandler.CREATE_COMMAND) + return db + + @classmethod + def _get_read_connection(cls, log_path: os.PathLike) -> sqlite3.Connection: + # A bit of a hack to open in read-only mode... + db = sqlite3.connect( + "file:" + str(log_path) + "?mode=ro", isolation_level=None, uri=True + ) + db.row_factory = sqlite3.Row + return db + + def _truncate(self, force: bool = False, keep_n: int = LOG_RETENTION_LIMIT): + assert not self.readonly + now = time.time() + if force or (now - self.last_cleanup > TIME_BETWEEN_CLEANUPS): + self.last_cleanup = now + self.db.execute( + """ + DELETE FROM guard_logs + WHERE id < ( + SELECT id FROM guard_logs ORDER BY id DESC LIMIT 1 OFFSET ? + ); + """, + (keep_n,), + ) + + def log( + self, + guard_name: str, + start_time: float, + end_time: float, + prevalidate_text: str, + postvalidate_text: str, + exception_text: str, + ): + assert not self.readonly + with self.db: + self.db.execute( + SQLiteTraceHandler.INSERT_COMMAND, + dict( + guard_name=guard_name, + start_time=start_time, + end_time=end_time, + prevalidate_text=prevalidate_text, + postvalidate_text=postvalidate_text, + exception_message=exception_text, + ), + ) + self._truncate() + + def log_entry(self, guard_log_entry: GuardTraceEntry): + assert not self.readonly + with self.db: + self.db.execute(SQLiteTraceHandler.INSERT_COMMAND, asdict(guard_log_entry)) + self._truncate() + + def log_validator(self, vlog: ValidatorLogs): + assert not self.readonly + maybe_outcome = ( + str(vlog.validation_result.outcome) + if ( + vlog.validation_result is not None + and hasattr(vlog.validation_result, "outcome") + ) + else "" + ) + with self.db: + self.db.execute( + SQLiteTraceHandler.INSERT_COMMAND, + dict( + guard_name=vlog.validator_name, + start_time=vlog.start_time if vlog.start_time else None, + end_time=vlog.end_time if vlog.end_time else 0.0, + prevalidate_text=to_string(vlog.value_before_validation), + postvalidate_text=to_string(vlog.value_after_validation), + exception_message=maybe_outcome, + ), + ) + self._truncate() + + def tail_logs( + self, start_offset_idx: int = 0, follow: bool = False + ) -> Iterator[GuardTraceEntry]: + """Returns an iterator to generate GuardLogEntries. @param + start_offset_idx : Start printing entries after this IDX. If. + + negative, this will instead start printing the LAST + start_offset_idx entries. @param follow : If follow is True, + will re-check the database for new entries after the first batch + is complete. If False (default), will return when entries are + exhausted. + """ + last_idx = start_offset_idx + cursor = self.db.cursor() + if last_idx < 0: + # We're indexing from the end, so do a quick check. + cursor.execute( + "SELECT id FROM guard_logs ORDER BY id DESC LIMIT 1 OFFSET ?;", + (-last_idx,), + ) + for row in cursor: + last_idx = row["id"] + sql = """ + SELECT + id, guard_name, start_time, end_time, prevalidate_text, + postvalidate_text, exception_message + FROM guard_logs + WHERE id > ? + ORDER BY start_time; + """ + cursor.execute(sql, (last_idx,)) + while True: + for row in cursor: + last_entry = GuardTraceEntry(**row) + last_idx = last_entry.id + yield last_entry + if not follow: + return + # If we're here we've run out of entries to tail. Fetch more: + cursor.execute(sql, (last_idx,)) diff --git a/guardrails/call_tracing/trace_entry.py b/guardrails/call_tracing/trace_entry.py new file mode 100644 index 000000000..6f807a9f1 --- /dev/null +++ b/guardrails/call_tracing/trace_entry.py @@ -0,0 +1,25 @@ +"""trace_entry.py. + +GuardTraceEntry is a dataclass which doesn't explicitly define the +schema of our logs, but serves as a nice, easy-to-use dataclass for when +we want to manipulate things programmatically. If performance and +filtering is a concern, it's probably worth writing the SQL directly +instead of filtering these in a for-loop. +""" + +from dataclasses import dataclass + + +@dataclass +class GuardTraceEntry: + id: int = -1 + guard_name: str = "" + start_time: float = 0.0 + end_time: float = 0.0 + prevalidate_text: str = "" + postvalidate_text: str = "" + exception_message: str = "" + + @property + def timedelta(self): + return self.end_time - self.start_time diff --git a/guardrails/call_tracing/trace_handler.py b/guardrails/call_tracing/trace_handler.py new file mode 100644 index 000000000..1e689f2d0 --- /dev/null +++ b/guardrails/call_tracing/trace_handler.py @@ -0,0 +1,71 @@ +"""trace_handler.py. + +A set of tools to track the behavior of guards, specifically with the intent of +collating the pre/post validation text and timing of guard calls. Uses a singleton to +share write access to a SQLite database across threads. + +By default, logs will be created in a temporary directory. This can be overridden by +setting GUARDRAILS_LOG_FILE_PATH in the environment. tracehandler.log_path will give +the full path of the current log file. + +# Reading logs (basic): +>>> reader = TraceHandler.get_reader() +>>> for t in reader.tail_logs(): +>>> print(t) + +# Reading logs (advanced): +>>> reader = TraceHandler.get_reader() +>>> reader.db.execute("SELECT * FROM guard_logs;") # Arbitrary SQL support. + +# Saving logs +>>> writer = TraceHandler() +>>> writer.log( +>>> "my_guard_name", 0.0, 1.0, "Raw LLM Output Text", "Sanitized", "exception?" +>>> ) +""" + +import os +import tempfile +import threading + +from guardrails.call_tracing.sqlite_trace_handler import SQLiteTraceHandler +from guardrails.call_tracing.tracer_mixin import TracerMixin + +# TODO: We should read this from guardrailsrc. +LOG_FILENAME = "guardrails_calls.db" +LOGFILE_PATH = os.environ.get( + "GUARDRAILS_LOG_FILE_PATH", # Document this environment variable. + os.path.join(tempfile.gettempdir(), LOG_FILENAME), +) + + +class TraceHandler(TracerMixin): + """TraceHandler wraps the internal _SQLiteTraceHandler to make it multi- + thread safe. + + Coupled with some write ahead journaling in the _SyncTrace internal, + we have a faux-multi-write multi-read interface for SQLite. + """ + + _instance = None + _lock = threading.Lock() + + def __new__(cls): + if cls._instance is None: + # We run two 'if None' checks so we don't have to call the mutex check for + # the cases where there's obviously no handler. Only do a check if there + # MIGHT not be a handler instantiated. + with cls._lock: + if cls._instance is None: + cls._instance = cls._create() + return cls._instance + + @classmethod + def _create(cls, path: os.PathLike = LOGFILE_PATH) -> TracerMixin: # type: ignore + return SQLiteTraceHandler(path, read_mode=False) + # To disable logging: + # return _BaseTraceHandler(path, read_mode=False) + + @classmethod + def get_reader(cls, path: os.PathLike = LOGFILE_PATH) -> TracerMixin: # type: ignore + return SQLiteTraceHandler(path, read_mode=True) diff --git a/guardrails/call_tracing/tracer_mixin.py b/guardrails/call_tracing/tracer_mixin.py new file mode 100644 index 000000000..76b1684f3 --- /dev/null +++ b/guardrails/call_tracing/tracer_mixin.py @@ -0,0 +1,34 @@ +"""tracer_mixin.py. + +This file defines our preferred tracer interface. It has a side effect +of acting as a 'noop' when we want to benchmark performance of a tracer. +""" + +import os +from typing import Iterator + +from guardrails.call_tracing.trace_entry import GuardTraceEntry +from guardrails.classes.validation.validator_logs import ValidatorLogs + + +class TracerMixin: + """The pads out the methods but is otherwise a noop.""" + + def __init__(self, log_path: os.PathLike, read_mode: bool): + self.db = None + + def log(self, *args, **kwargs): + pass + + def log_entry(self, guard_log_entry: GuardTraceEntry): + pass + + def log_validator(self, vlog: ValidatorLogs): + pass + + def tail_logs( + self, + start_offset_idx: int = 0, + follow: bool = False, + ) -> Iterator[GuardTraceEntry]: + yield from [] diff --git a/guardrails/classes/__init__.py b/guardrails/classes/__init__.py index 066311801..16bf9ac0e 100644 --- a/guardrails/classes/__init__.py +++ b/guardrails/classes/__init__.py @@ -1,6 +1,21 @@ from guardrails.classes.credentials import Credentials from guardrails.classes.input_type import InputType from guardrails.classes.output_type import OT +from guardrails.classes.validation.validation_result import ( + ValidationResult, + PassResult, + FailResult, + ErrorSpan, +) from guardrails.classes.validation_outcome import ValidationOutcome -__all__ = ["ValidationOutcome", "OT", "InputType", "Credentials"] +__all__ = [ + "Credentials", + "ErrorSpan", + "InputType", + "OT", + "ValidationResult", + "PassResult", + "FailResult", + "ValidationOutcome", +] diff --git a/guardrails/classes/credentials.py b/guardrails/classes/credentials.py index cde58a199..3c251476c 100644 --- a/guardrails/classes/credentials.py +++ b/guardrails/classes/credentials.py @@ -6,6 +6,8 @@ from guardrails.classes.generic.serializeable import Serializeable +BOOL_CONFIGS = set(["no_metrics", "enable_metrics", "use_remote_inferencing"]) + @dataclass class Credentials(Serializeable): @@ -13,6 +15,7 @@ class Credentials(Serializeable): token: Optional[str] = None no_metrics: Optional[bool] = False enable_metrics: Optional[bool] = True + use_remote_inferencing: Optional[bool] = True @staticmethod def _to_bool(value: str) -> Optional[bool]: @@ -22,6 +25,12 @@ def _to_bool(value: str) -> Optional[bool]: return False return None + @staticmethod + def has_rc_file() -> bool: + home = expanduser("~") + guardrails_rc = os.path.join(home, ".guardrailsrc") + return os.path.exists(guardrails_rc) + @staticmethod def from_rc_file(logger: Optional[logging.Logger] = None) -> "Credentials": try: @@ -29,14 +38,14 @@ def from_rc_file(logger: Optional[logging.Logger] = None) -> "Credentials": logger = logging.getLogger() home = expanduser("~") guardrails_rc = os.path.join(home, ".guardrailsrc") - with open(guardrails_rc) as rc_file: + with open(guardrails_rc, encoding="utf-8") as rc_file: lines = rc_file.readlines() filtered_lines = list(filter(lambda l: l.strip(), lines)) creds = {} for line in filtered_lines: line_content = line.split("=", 1) if len(line_content) != 2: - logger.warn( + logger.warning( """ Invalid line found in .guardrailsrc file! All lines in this file should follow the format: key=value @@ -48,7 +57,7 @@ def from_rc_file(logger: Optional[logging.Logger] = None) -> "Credentials": key, value = line_content key = key.strip() value = value.strip() - if key == "no_metrics" or key == "enable_metrics": + if key in BOOL_CONFIGS: value = Credentials._to_bool(value) creds[key] = value diff --git a/guardrails/classes/execution/__init__.py b/guardrails/classes/execution/__init__.py new file mode 100644 index 000000000..f0e5aef0a --- /dev/null +++ b/guardrails/classes/execution/__init__.py @@ -0,0 +1,3 @@ +from guardrails.classes.execution.guard_execution_options import GuardExecutionOptions + +__all__ = ["GuardExecutionOptions"] diff --git a/guardrails/classes/execution/guard_execution_options.py b/guardrails/classes/execution/guard_execution_options.py new file mode 100644 index 000000000..f46f68e88 --- /dev/null +++ b/guardrails/classes/execution/guard_execution_options.py @@ -0,0 +1,12 @@ +from typing import Dict, List, Optional +from dataclasses import dataclass + + +@dataclass +class GuardExecutionOptions: + prompt: Optional[str] = None + instructions: Optional[str] = None + msg_history: Optional[List[Dict]] = None + reask_prompt: Optional[str] = None + reask_instructions: Optional[str] = None + num_reasks: Optional[int] = None diff --git a/guardrails/classes/generic/__init__.py b/guardrails/classes/generic/__init__.py index fd1909521..52f50b212 100644 --- a/guardrails/classes/generic/__init__.py +++ b/guardrails/classes/generic/__init__.py @@ -1,4 +1,5 @@ +from guardrails.classes.generic.arbitrary_model import ArbitraryModel from guardrails.classes.generic.serializeable import Serializeable from guardrails.classes.generic.stack import Stack -__all__ = ["Stack", "Serializeable"] +__all__ = ["ArbitraryModel", "Stack", "Serializeable"] diff --git a/guardrails/classes/generic/arbitrary_model.py b/guardrails/classes/generic/arbitrary_model.py new file mode 100644 index 000000000..876c978ac --- /dev/null +++ b/guardrails/classes/generic/arbitrary_model.py @@ -0,0 +1,7 @@ +from pydantic import BaseModel, ConfigDict + + +class ArbitraryModel(BaseModel): + """Empty Pydantic model with a config that allows arbitrary types.""" + + model_config = ConfigDict(arbitrary_types_allowed=True) diff --git a/guardrails/classes/history/__init__.py b/guardrails/classes/history/__init__.py index 622b0cd18..469fdbfee 100644 --- a/guardrails/classes/history/__init__.py +++ b/guardrails/classes/history/__init__.py @@ -4,4 +4,4 @@ from guardrails.classes.history.iteration import Iteration from guardrails.classes.history.outputs import Outputs -__all__ = ["CallInputs", "Call", "Inputs", "Iteration", "Outputs"] +__all__ = ["Call", "Iteration", "Inputs", "Outputs", "CallInputs"] diff --git a/guardrails/classes/history/call.py b/guardrails/classes/history/call.py index 6598e3c12..1f2498900 100644 --- a/guardrails/classes/history/call.py +++ b/guardrails/classes/history/call.py @@ -1,31 +1,48 @@ -from typing import Dict, Optional, Union - -from pydantic import Field, PrivateAttr +from typing import Any, Dict, List, Optional, Union +from builtins import id as object_id +from pydantic import Field from rich.panel import Panel from rich.pretty import pretty_repr from rich.tree import Tree -from typing_extensions import deprecated +from guardrails_api_client import Call as ICall +from guardrails.actions.filter import Filter +from guardrails.actions.refrain import Refrain +from guardrails.actions.reask import merge_reask_output from guardrails.classes.generic.stack import Stack from guardrails.classes.history.call_inputs import CallInputs from guardrails.classes.history.iteration import Iteration +from guardrails.classes.generic.arbitrary_model import ArbitraryModel +from guardrails.classes.validation.validation_result import ValidationResult from guardrails.constants import error_status, fail_status, not_run_status, pass_status from guardrails.prompt.instructions import Instructions from guardrails.prompt.prompt import Prompt -from guardrails.utils.logs_utils import ValidatorLogs, merge_reask_output -from guardrails.utils.pydantic_utils import ArbitraryModel -from guardrails.utils.reask_utils import ( +from guardrails.classes.validation.validator_logs import ValidatorLogs +from guardrails.actions.reask import ( ReAsk, gather_reasks, sub_reasks_with_fixed_values, ) -from guardrails.utils.safe_get import get_value_from_path -from guardrails.validator_base import Filter, Refrain, ValidationResult +from guardrails.schema.parser import get_value_from_path # We can't inherit from Iteration because python # won't let you override a class attribute with a managed attribute -class Call(ArbitraryModel): +class Call(ICall, ArbitraryModel): + """A Call represents a single execution of a Guard. One Call is created + each time the user invokes the `Guard.__call__`, `Guard.parse`, or + `Guard.validate` method. + + Attributes: + iterations (Stack[Iteration]): A stack of iterations + for the initial validation round + and one for each reask that occurs during a Call. + inputs (CallInputs): The inputs as passed in to + `Guard.__call__`, `Guard.parse`, or `Guard.validate` + exception (Optional[Exception]): The exception that interrupted + the Guard execution. + """ + iterations: Stack[Iteration] = Field( description="A stack of iterations for each" "step/reask that occurred during this call." @@ -33,7 +50,10 @@ class Call(ArbitraryModel): inputs: CallInputs = Field( description="The inputs as passed in to Guard.__call__ or Guard.parse" ) - _exception: Optional[Exception] = PrivateAttr() + exception: Optional[Exception] = Field( + description="The exception that interrupted the run.", + default=None, + ) # Prevent Pydantic from changing our types # Without this, Pydantic casts iterations to a list @@ -43,16 +63,13 @@ def __init__( inputs: Optional[CallInputs] = None, exception: Optional[Exception] = None, ): + call_id = str(object_id(self)) iterations = iterations or Stack() inputs = inputs or CallInputs() - super().__init__( - iterations=iterations, # type: ignore - inputs=inputs, # type: ignore - _exception=exception, # type: ignore - ) + super().__init__(id=call_id, iterations=iterations, inputs=inputs) # type: ignore - pyright doesn't understand pydantic overrides self.iterations = iterations self.inputs = inputs - self._exception = exception + self.exception = exception @property def prompt(self) -> Optional[str]: @@ -193,21 +210,13 @@ def raw_outputs(self) -> Stack[str]: ) @property - def parsed_outputs(self) -> Stack[Union[str, Dict]]: + def parsed_outputs(self) -> Stack[Union[str, List, Dict]]: """The outputs from the LLM after undergoing parsing but before validation.""" return Stack(*[i.outputs.parsed_output for i in self.iterations]) @property - @deprecated( - """'Call.validation_output' is deprecated and will be removed in \ -versions 0.5.0 and beyond. Use 'validation_response' instead.""" - ) - def validation_output(self) -> Optional[Union[str, Dict, ReAsk]]: - return self.validation_response - - @property - def validation_response(self) -> Optional[Union[str, Dict, ReAsk]]: + def validation_response(self) -> Optional[Union[str, List, Dict, ReAsk]]: """The aggregated responses from the validation process across all iterations within the current call. @@ -252,7 +261,7 @@ def validation_response(self) -> Optional[Union[str, Dict, ReAsk]]: return merged_validation_responses @property - def fixed_output(self) -> Optional[Union[str, Dict]]: + def fixed_output(self) -> Optional[Union[str, List, Dict]]: """The cumulative output from the validation process across all current iterations with any automatic fixes applied. @@ -261,7 +270,7 @@ def fixed_output(self) -> Optional[Union[str, Dict]]: return sub_reasks_with_fixed_values(self.validation_response) @property - def guarded_output(self) -> Optional[Union[str, Dict]]: + def guarded_output(self) -> Optional[Union[str, List, Dict]]: """The complete validated output after all stages of validation are completed. @@ -293,18 +302,6 @@ def guarded_output(self) -> Optional[Union[str, Dict]]: if all_noop: return last_iteration.guarded_output - @property - @deprecated( - """'Call.validated_output' is deprecated and will be removed in \ -versions 0.5.0 and beyond. Use 'guarded_output' instead.""" - ) - def validated_output(self) -> Optional[Union[str, Dict]]: - """The output from the LLM after undergoing validation. - - This will only have a value if the Guard is in a passing state. - """ - return self.guarded_output - @property def reasks(self) -> Stack[ReAsk]: """Reasks generated during validation that could not be automatically @@ -329,21 +326,12 @@ def validator_logs(self) -> Stack[ValidatorLogs]: def error(self) -> Optional[str]: """The error message from any exception that raised and interrupted the run.""" - if self._exception: - return str(self._exception) + if self.exception: + return str(self.exception) elif self.iterations.empty(): return None return self.iterations.last.error # type: ignore - @property - def exception(self) -> Optional[Exception]: - """The exception that interrupted the run.""" - if self._exception: - return self._exception - elif self.iterations.empty(): - return None - return self.iterations.last.exception # type: ignore - @property def failed_validations(self) -> Stack[ValidatorLogs]: """The validator logs for any validations that failed during the @@ -420,3 +408,36 @@ def tree(self) -> Tree: def __str__(self) -> str: return pretty_repr(self) + + def to_interface(self) -> ICall: + return ICall( + id=self.id, + iterations=[i.to_interface() for i in self.iterations], + inputs=self.inputs.to_interface(), + exception=self.error, + ) + + def to_dict(self) -> Dict[str, Any]: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_call: ICall) -> "Call": + iterations = Stack( + *[Iteration.from_interface(i) for i in (i_call.iterations or [])] + ) + inputs = ( + CallInputs.from_interface(i_call.inputs) if i_call.inputs else CallInputs() + ) + exception = Exception(i_call.exception) if i_call.exception else None + call_inst = cls(iterations=iterations, inputs=inputs, exception=exception) + call_inst.id = i_call.id + return call_inst + + # TODO: Necessary to GET /guards/{guard_name}/history/{call_id} + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "Call": + i_call = ICall.from_dict(obj) + + if i_call: + return cls.from_interface(i_call) + return Call() diff --git a/guardrails/classes/history/call_inputs.py b/guardrails/classes/history/call_inputs.py index 2837afb0e..4aa2363f8 100644 --- a/guardrails/classes/history/call_inputs.py +++ b/guardrails/classes/history/call_inputs.py @@ -2,10 +2,27 @@ from pydantic import Field +from guardrails_api_client import CallInputs as ICallInputs from guardrails.classes.history.inputs import Inputs +from guardrails.classes.generic.arbitrary_model import ArbitraryModel -class CallInputs(Inputs): +class CallInputs(Inputs, ICallInputs, ArbitraryModel): + """CallInputs represent the input data that is passed into the Guard from + the user. Inherits from Inputs with the below overrides and additional + attributes. + + Attributes: + llm_api (Optional[Callable[[Any], Awaitable[Any]]]): The LLM function + provided by the user during Guard.__call__ or Guard.parse. + prompt (Optional[str]): The prompt string as provided by the user. + instructions (Optional[str]): The instructions string as provided by the user. + args (List[Any]): Additional arguments for the LLM as provided by the user. + Default []. + kwargs (Dict[str, Any]): Additional keyword-arguments for + the LLM as provided by the user. Default {}. + """ + llm_api: Optional[Callable[[Any], Awaitable[Any]]] = Field( description="The LLM function provided by the user" "during Guard.__call__ or Guard.parse.", @@ -25,3 +42,45 @@ class CallInputs(Inputs): description="Additional keyword-arguments for the LLM as provided by the user.", default_factory=dict, ) + + def to_interface(self) -> ICallInputs: + inputs = super().to_interface().to_dict() or {} + inputs["args"] = self.args + # TODO: Better way to prevent creds from being logged, + # if they're passed in as kwargs to the LLM + redacted_kwargs = {} + for k, v in self.kwargs.items(): + if ("key" in k.lower() or "token" in k.lower()) and isinstance(v, str): + redaction_length = len(v) - 4 + stars = "*" * redaction_length + redacted_kwargs[k] = f"{stars}{v[-4:]}" + else: + redacted_kwargs[k] = v + inputs["kwargs"] = redacted_kwargs + return ICallInputs(**inputs) + + def to_dict(self) -> Dict[str, Any]: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_call_inputs: ICallInputs) -> "CallInputs": + return cls( + llm_api=None, + llm_output=i_call_inputs.llm_output, + instructions=i_call_inputs.instructions, + prompt=i_call_inputs.prompt, + msg_history=i_call_inputs.msg_history, + prompt_params=i_call_inputs.prompt_params, + num_reasks=i_call_inputs.num_reasks, + metadata=i_call_inputs.metadata, + full_schema_reask=(i_call_inputs.full_schema_reask is True), + stream=(i_call_inputs.stream is True), + args=(i_call_inputs.args or []), + kwargs=(i_call_inputs.kwargs or {}), + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]): + i_call_inputs = ICallInputs.from_dict(obj) or ICallInputs() + + return cls.from_interface(i_call_inputs) diff --git a/guardrails/classes/history/inputs.py b/guardrails/classes/history/inputs.py index 07a34920e..0e6c2ea8f 100644 --- a/guardrails/classes/history/inputs.py +++ b/guardrails/classes/history/inputs.py @@ -2,13 +2,37 @@ from pydantic import Field +from guardrails_api_client import Inputs as IInputs +from guardrails.classes.generic.arbitrary_model import ArbitraryModel from guardrails.llm_providers import PromptCallableBase from guardrails.prompt.instructions import Instructions from guardrails.prompt.prompt import Prompt -from guardrails.utils.pydantic_utils import ArbitraryModel -class Inputs(ArbitraryModel): +class Inputs(IInputs, ArbitraryModel): + """Inputs represent the input data that is passed into the validation loop. + + Attributes: + llm_api (Optional[PromptCallableBase]): The constructed class + for calling the LLM. + llm_output (Optional[str]): The string output from an + external LLM call provided by the user via Guard.parse. + instructions (Optional[Instructions]): The constructed + Instructions class for chat model calls. + prompt (Optional[Prompt]): The constructed Prompt class. + msg_history (Optional[List[Dict]]): The message history + provided by the user for chat model calls. + prompt_params (Optional[Dict]): The parameters provided + by the user that will be formatted into the final LLM prompt. + num_reasks (Optional[int]): The total number of reasks allowed; + user provided or defaulted. + metadata (Optional[Dict[str, Any]]): The metadata provided + by the user to be used during validation. + full_schema_reask (Optional[bool]): Whether reasks we + performed across the entire schema or at the field level. + stream (Optional[bool]): Whether or not streaming was used. + """ + llm_api: Optional[PromptCallableBase] = Field( description="The constructed class for calling the LLM.", default=None ) @@ -33,7 +57,7 @@ class Inputs(ArbitraryModel): "that will be formatted into the final LLM prompt.", default=None, ) - num_reasks: int = Field( + num_reasks: Optional[int] = Field( description="The total number of reasks allowed; user provided or defaulted.", default=None, ) @@ -41,7 +65,7 @@ class Inputs(ArbitraryModel): description="The metadata provided by the user to be used during validation.", default=None, ) - full_schema_reask: bool = Field( + full_schema_reask: Optional[bool] = Field( description="Whether to perform reasks across the entire schema" "or at the field level.", default=None, @@ -50,3 +74,78 @@ class Inputs(ArbitraryModel): description="Whether to use streaming.", default=False, ) + + def to_interface(self) -> IInputs: + serialized_msg_history = None + if self.msg_history: + serialized_msg_history = [] + for msg in self.msg_history: + ser_msg = {**msg} + content = ser_msg.get("content") + if content: + ser_msg["content"] = ( + content.source if isinstance(content, Prompt) else content + ) + serialized_msg_history.append(ser_msg) + + instructions = ( + self.instructions.source + if isinstance(self.instructions, Instructions) + else self.instructions + ) + + prompt = self.prompt.source if isinstance(self.prompt, Prompt) else self.prompt + + return IInputs( + llm_api=str(self.llm_api) if self.llm_api else None, # type: ignore - pyright doesn't understand aliases + llm_output=self.llm_output, # type: ignore - pyright doesn't understand aliases + instructions=instructions, + prompt=prompt, + msg_history=serialized_msg_history, # type: ignore - pyright doesn't understand aliases + prompt_params=self.prompt_params, # type: ignore - pyright doesn't understand aliases + num_reasks=self.num_reasks, # type: ignore - pyright doesn't understand aliases + metadata=self.metadata, + full_schema_reask=self.full_schema_reask, # type: ignore - pyright doesn't understand aliases + stream=self.stream, + ) + + def to_dict(self) -> Dict[str, Any]: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_inputs: IInputs) -> "Inputs": + deserialized_msg_history = None + if i_inputs.msg_history: + deserialized_msg_history = [] + for msg in i_inputs.msg_history: + ser_msg = {**msg} + content = ser_msg.get("content") + if content: + ser_msg["content"] = Prompt(content) + deserialized_msg_history.append(ser_msg) + + instructions = ( + Instructions(i_inputs.instructions) if i_inputs.instructions else None + ) + + prompt = Prompt(i_inputs.prompt) if i_inputs.prompt else None + num_reasks = ( + int(i_inputs.num_reasks) if i_inputs.num_reasks is not None else None + ) + return cls( + llm_api=None, + llm_output=i_inputs.llm_output, + instructions=instructions, + prompt=prompt, + msg_history=deserialized_msg_history, + prompt_params=i_inputs.prompt_params, + num_reasks=num_reasks, + metadata=i_inputs.metadata, + full_schema_reask=(i_inputs.full_schema_reask is True), + stream=(i_inputs.stream is True), + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "Inputs": + i_inputs = IInputs.from_dict(obj) or IInputs() + return cls.from_interface(i_inputs) diff --git a/guardrails/classes/history/iteration.py b/guardrails/classes/history/iteration.py index a8fb67ada..45c60baab 100644 --- a/guardrails/classes/history/iteration.py +++ b/guardrails/classes/history/iteration.py @@ -1,24 +1,36 @@ -from typing import Dict, List, Optional, Sequence, Union - +from typing import Any, Dict, List, Optional, Sequence, Union +from builtins import id as object_id from pydantic import Field from rich.console import Group from rich.panel import Panel from rich.pretty import pretty_repr from rich.table import Table -from typing_extensions import deprecated +from guardrails_api_client import Iteration as IIteration from guardrails.classes.generic.stack import Stack from guardrails.classes.history.inputs import Inputs from guardrails.classes.history.outputs import Outputs +from guardrails.classes.generic.arbitrary_model import ArbitraryModel from guardrails.logger import get_scope_handler from guardrails.prompt.prompt import Prompt -from guardrails.utils.logs_utils import ValidatorLogs -from guardrails.utils.pydantic_utils import ArbitraryModel -from guardrails.utils.reask_utils import ReAsk -from guardrails.validator_base import ErrorSpan +from guardrails.classes.validation.validator_logs import ValidatorLogs +from guardrails.actions.reask import ReAsk +from guardrails.classes.validation.validation_result import ErrorSpan + +class Iteration(IIteration, ArbitraryModel): + """An Iteration represents a single iteration of the validation loop + including a single call to the LLM if applicable. + + Attributes: + id (str): The unique identifier for the iteration. + call_id (str): The unique identifier for the Call + that this iteration is a part of. + index (int): The index of this iteration within the Call. + inputs (Inputs): The inputs for the validation loop. + outputs (Outputs): The outputs from the validation loop. + """ -class Iteration(ArbitraryModel): # I think these should be containered since their names slightly overlap with # outputs, but could be convinced otherwise inputs: Inputs = Field( @@ -29,6 +41,26 @@ class Iteration(ArbitraryModel): description="The outputs from the iteration/step.", default_factory=Outputs ) + def __init__( + self, + call_id: str, + index: int, + inputs: Optional[Inputs] = None, + outputs: Optional[Outputs] = None, + ): + iteration_id = str(object_id(self)) + inputs = inputs or Inputs() + outputs = outputs or Outputs() + super().__init__( + id=iteration_id, + call_id=call_id, # type: ignore + index=index, + inputs=inputs, + outputs=outputs, + ) + self.inputs = inputs + self.outputs = outputs + @property def logs(self) -> Stack[str]: """Returns the logs from this iteration as a stack.""" @@ -72,13 +104,13 @@ def raw_output(self) -> Optional[str]: return self.outputs.raw_output @property - def parsed_output(self) -> Optional[Union[str, Dict]]: + def parsed_output(self) -> Optional[Union[str, List, Dict]]: """The output from the LLM after undergoing parsing but before validation.""" return self.outputs.parsed_output @property - def validation_response(self) -> Optional[Union[ReAsk, str, Dict]]: + def validation_response(self) -> Optional[Union[ReAsk, str, List, Dict]]: """The response from a single stage of validation. Validation response is the output of a single stage of validation @@ -90,19 +122,7 @@ def validation_response(self) -> Optional[Union[ReAsk, str, Dict]]: return self.outputs.validation_response @property - @deprecated( - """'Iteration.validation_output' is deprecated and will be removed in \ -versions 0.5.0 and beyond. Use 'validation_response' instead.""" - ) - def validation_output(self) -> Optional[Union[ReAsk, str, Dict]]: - """The output from the validation process. - - Could be a combination of valid output and ReAsks - """ - return self.validation_response - - @property - def guarded_output(self) -> Optional[Union[str, Dict]]: + def guarded_output(self) -> Optional[Union[str, List, Dict]]: """Any valid values after undergoing validation. Some values in the validated output may be "fixed" values that @@ -111,19 +131,6 @@ def guarded_output(self) -> Optional[Union[str, Dict]]: """ return self.outputs.guarded_output - @property - @deprecated( - """'Iteration.validated_output' is deprecated and will be removed in \ -versions 0.5.0 and beyond. Use 'guarded_output' instead.""" - ) - def validated_output(self) -> Optional[Union[str, Dict]]: - """The valid output from the LLM after undergoing validation. - - Could be only a partial structure if field level reasks occur. - Could contain fixed values. - """ - return self.outputs.guarded_output - @property def reasks(self) -> Sequence[ReAsk]: """Reasks generated during validation. @@ -241,3 +248,45 @@ def create_msg_history_table( def __str__(self) -> str: return pretty_repr(self) + + def to_interface(self) -> IIteration: + return IIteration( + id=self.id, + call_id=self.call_id, # type: ignore + index=self.index, + inputs=self.inputs.to_interface(), + outputs=self.outputs.to_interface(), + ) + + def to_dict(self) -> Dict: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_iteration: IIteration) -> "Iteration": + inputs = ( + Inputs.from_interface(i_iteration.inputs) if i_iteration.inputs else None + ) + outputs = ( + Outputs.from_interface(i_iteration.outputs) if i_iteration.outputs else None + ) + iteration = cls( + call_id=i_iteration.call_id, + index=i_iteration.index, + inputs=inputs, + outputs=outputs, + ) + iteration.id = i_iteration.id + return iteration + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "Iteration": + id = obj.get("id", "0") + call_id = obj.get("callId", obj.get("call_id", "0")) + index = obj.get("index", 0) + i_iteration = IIteration.from_dict(obj) or IIteration( + id=id, + call_id=call_id, # type: ignore + index=index, # type: ignore + ) + + return cls.from_interface(i_iteration) diff --git a/guardrails/classes/history/outputs.py b/guardrails/classes/history/outputs.py index ead39de20..a2c21ac1e 100644 --- a/guardrails/classes/history/outputs.py +++ b/guardrails/classes/history/outputs.py @@ -1,45 +1,74 @@ -from typing import Dict, List, Optional, Sequence, Union +from typing import Any, Dict, List, Optional, Union from pydantic import Field -from typing_extensions import deprecated +from guardrails_api_client import ( + Outputs as IOutputs, + OutputsParsedOutput, + OutputsValidationResponse, +) from guardrails.constants import error_status, fail_status, not_run_status, pass_status -from guardrails.utils.llm_response import LLMResponse -from guardrails.utils.logs_utils import ValidatorLogs -from guardrails.utils.pydantic_utils import ArbitraryModel -from guardrails.utils.reask_utils import ReAsk -from guardrails.validator_base import ErrorSpan, FailResult, ValidationResult +from guardrails.classes.llm.llm_response import LLMResponse +from guardrails.classes.generic.arbitrary_model import ArbitraryModel +from guardrails.classes.validation.validator_logs import ValidatorLogs +from guardrails.actions.reask import ReAsk +from guardrails.classes.validation.validation_result import ( + ErrorSpan, + FailResult, + ValidationResult, +) -class Outputs(ArbitraryModel): +class Outputs(IOutputs, ArbitraryModel): + """Outputs represent the data that is output from the validation loop. + + Attributes: + llm_response_info (Optional[LLMResponse]): Information from the LLM response + raw_output (Optional[str]): The exact output from the LLM. + parsed_output (Optional[Union[str, List, Dict]]): The output parsed from the LLM + response as it was passed into validation. + validation_response (Optional[Union[str, ReAsk, List, Dict]]): The response + from the validation process. + guarded_output (Optional[Union[str, List, Dict]]): Any valid values after + undergoing validation. + Some values may be "fixed" values that were corrected during validation. + This property may be a partial structure if field level reasks occur. + reasks (List[ReAsk]): Information from the validation process used to construct + a ReAsk to the LLM on validation failure. Default []. + validator_logs (List[ValidatorLogs]): The results of each individual + validation. Default []. + error (Optional[str]): The error message from any exception that raised + and interrupted the process. + exception (Optional[Exception]): The exception that interrupted the process. + """ + llm_response_info: Optional[LLMResponse] = Field( description="Information from the LLM response.", default=None ) raw_output: Optional[str] = Field( description="The exact output from the LLM.", default=None ) - parsed_output: Optional[Union[str, Dict]] = Field( + parsed_output: Optional[Union[str, List, Dict]] = Field( description="The output parsed from the LLM response" "as it was passed into validation.", default=None, ) - validation_response: Optional[Union[str, ReAsk, Dict]] = Field( + validation_response: Optional[Union[str, ReAsk, List, Dict]] = Field( description="The response from the validation process.", default=None ) - guarded_output: Optional[Union[str, Dict]] = Field( + guarded_output: Optional[Union[str, List, Dict]] = Field( description="""Any valid values after undergoing validation. Some values may be "fixed" values that were corrected during validation. This property may be a partial structure if field level reasks occur.""", default=None, ) - reasks: Sequence[ReAsk] = Field( + reasks: List[ReAsk] = Field( description="Information from the validation process" "used to construct a ReAsk to the LLM on validation failure.", default_factory=list, ) # TODO: Rename this; - # TODO: Add json_path to ValidatorLogs to specify what property it applies to validator_logs: List[ValidatorLogs] = Field( description="The results of each individual validation.", default_factory=list ) @@ -82,23 +111,31 @@ def error_spans_in_output(self) -> List[ErrorSpan]: These indices are relative to the complete LLM output. """ - total_len = 0 + # map of total length to validator + total_len_by_validator = {} spans_in_output = [] for log in self.validator_logs: + validator_name = log.validator_name + if total_len_by_validator.get(validator_name) is None: + total_len_by_validator[validator_name] = 0 result = log.validation_result if isinstance(result, FailResult): if result.error_spans is not None: for error_span in result.error_spans: spans_in_output.append( ErrorSpan( - start=error_span.start + total_len, - end=error_span.end + total_len, + start=error_span.start + + total_len_by_validator[validator_name], + end=error_span.end + + total_len_by_validator[validator_name], reason=error_span.reason, ) ) if isinstance(result, ValidationResult): if result and result.validated_chunk is not None: - total_len += len(result.validated_chunk) + total_len_by_validator[validator_name] += len( + result.validated_chunk + ) return spans_in_output @property @@ -127,18 +164,80 @@ def status(self) -> str: return fail_status return pass_status - @property - @deprecated( - """'Outputs.validation_output' is deprecated and will be removed in \ -versions 0.5.0 and beyond. Use 'validation_response' instead.""" - ) - def validation_output(self) -> Optional[Union[str, ReAsk, Dict]]: - return self.validation_response + def to_interface(self) -> IOutputs: + return IOutputs( + llm_response_info=( # type: ignore - pydantic alias + self.llm_response_info.to_interface() + if self.llm_response_info + else None + ), + raw_output=self.raw_output, # type: ignore - pydantic alias + parsed_output=( # type: ignore - pydantic alias + OutputsParsedOutput(self.parsed_output) if self.parsed_output else None + ), + validation_response=( # type: ignore - pydantic alias + OutputsValidationResponse(self.validation_response) + if self.validation_response + else None + ), + guarded_output=( # type: ignore - pydantic alias + OutputsParsedOutput(self.guarded_output) + if self.guarded_output + else None + ), + reasks=self.reasks, # type: ignore - pydantic alias + validator_logs=[ # type: ignore - pydantic alias + v.to_interface() + for v in self.validator_logs + if isinstance(v, ValidatorLogs) + ], + error=self.error, + ) - @property - @deprecated( - """'Outputs.validated_output' is deprecated and will be removed in \ -versions 0.5.0 and beyond. Use 'guarded_output' instead.""" - ) - def validated_output(self) -> Optional[Union[str, ReAsk, Dict]]: - return self.guarded_output + def to_dict(self) -> Dict[str, Any]: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_outputs: IOutputs) -> "Outputs": + reasks = [] + if i_outputs.reasks: + reasks = [ReAsk.from_interface(r) for r in i_outputs.reasks] + + validator_logs = [] + if i_outputs.validator_logs: + validator_logs = [ + ValidatorLogs.from_interface(v) for v in i_outputs.validator_logs + ] + + return cls( + llm_response_info=( # type: ignore + LLMResponse.from_interface(i_outputs.llm_response_info) + if i_outputs.llm_response_info + else None + ), + raw_output=i_outputs.raw_output, # type: ignore + parsed_output=( # type: ignore + i_outputs.parsed_output.actual_instance + if i_outputs.parsed_output + else None + ), + validation_response=( # type: ignore + i_outputs.validation_response.actual_instance + if i_outputs.validation_response + else None + ), + guarded_output=( # type: ignore + i_outputs.guarded_output.actual_instance + if i_outputs.guarded_output + else None + ), + reasks=reasks, # type: ignore + validator_logs=validator_logs, # type: ignore + error=i_outputs.error, + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "Outputs": + i_outputs = IOutputs.from_dict(obj) or IOutputs() + + return cls.from_interface(i_outputs) diff --git a/guardrails/classes/llm/llm_response.py b/guardrails/classes/llm/llm_response.py new file mode 100644 index 000000000..d26e37a35 --- /dev/null +++ b/guardrails/classes/llm/llm_response.py @@ -0,0 +1,87 @@ +import asyncio +from typing import Any, Dict, Iterable, Optional, AsyncIterable + +from guardrails_api_client import LLMResponse as ILLMResponse +from pydantic.config import ConfigDict + + +# TODO: Move this somewhere that makes sense +def async_to_sync(awaitable): + loop = asyncio.get_event_loop() + return loop.run_until_complete(awaitable) + + +# TODO: We might be able to delete this +class LLMResponse(ILLMResponse): + """Standard information collection from LLM responses to feed the + validation loop. + + Attributes: + output (str): The output from the LLM. + stream_output (Optional[Iterable]): A stream of output from the LLM. + Default None. + async_stream_output (Optional[AsyncIterable]): An async stream of output + from the LLM. Default None. + prompt_token_count (Optional[int]): The number of tokens in the prompt. + Default None. + response_token_count (Optional[int]): The number of tokens in the response. + Default None. + """ + + # Pydantic Config + model_config = ConfigDict(arbitrary_types_allowed=True) + + prompt_token_count: Optional[int] = None + response_token_count: Optional[int] = None + output: str + stream_output: Optional[Iterable] = None + async_stream_output: Optional[AsyncIterable] = None + + def to_interface(self) -> ILLMResponse: + stream_output = None + if self.stream_output: + stream_output = [str(so) for so in self.stream_output] + + async_stream_output = None + if self.async_stream_output: + async_stream_output = [str(async_to_sync(so)) for so in self.stream_output] # type: ignore - we just established it isn't None + + return ILLMResponse( + prompt_token_count=self.prompt_token_count, # type: ignore - pyright doesn't understand aliases + response_token_count=self.response_token_count, # type: ignore - pyright doesn't understand aliases + output=self.output, + stream_output=stream_output, # type: ignore - pyright doesn't understand aliases + async_stream_output=async_stream_output, # type: ignore - pyright doesn't understand aliases + ) + + def to_dict(self) -> Dict[str, Any]: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_llm_response: ILLMResponse) -> "LLMResponse": + stream_output = None + if i_llm_response.stream_output: + stream_output = [so for so in i_llm_response.stream_output] + + async_stream_output = None + if i_llm_response.async_stream_output: + + async def async_iter(): + for aso in i_llm_response.async_stream_output: # type: ignore - just verified it isn't None... + yield aso + + async_stream_output = async_iter() + + return cls( + prompt_token_count=i_llm_response.prompt_token_count, + response_token_count=i_llm_response.response_token_count, + output=i_llm_response.output, + stream_output=stream_output, + async_stream_output=async_stream_output, + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "LLMResponse": + i_llm_response = super().from_dict(obj) or ILLMResponse(output="") + + return cls.from_interface(i_llm_response) diff --git a/guardrails/classes/output_type.py b/guardrails/classes/output_type.py index 2aff9fc82..e1b050921 100644 --- a/guardrails/classes/output_type.py +++ b/guardrails/classes/output_type.py @@ -1,3 +1,63 @@ -from typing import Dict, List, TypeVar +# TODO: Move this file to guardrails.types +from enum import Enum +from typing import Any, Dict, List, Optional, TypeVar, Union +from guardrails_api_client import SimpleTypes OT = TypeVar("OT", str, List, Dict) + + +# TODO: Move this to types.py +# It's only here for historical reasons +class OutputTypes(str, Enum): + STRING = "str" + LIST = "list" + DICT = "dict" + + @staticmethod + def get(key: Optional[Union[str, "OutputTypes"]], default=None): + try: + if not key: + return default + if isinstance(key, OutputTypes): + return key + return OutputTypes[key] + except Exception: + return default + + @classmethod + def __from_json_schema__(cls, json_schema: Dict[str, Any]) -> "OutputTypes": + if not json_schema: + return cls("str") + + schema_type = json_schema.get("type") + if schema_type == SimpleTypes.STRING: + return cls("str") + elif schema_type == SimpleTypes.OBJECT: + return cls("dict") + elif schema_type == SimpleTypes.ARRAY: + return cls("list") + + all_of = json_schema.get("allOf") + if all_of: + return cls("dict") + + one_of: List[Dict[str, Any]] = [ + s + for s in json_schema.get("oneOf", []) + if isinstance(s, dict) and "type" in s + ] + if one_of: + first_sub_schema = one_of[0] + return cls.__from_json_schema__(first_sub_schema) + + any_of: List[Dict[str, Any]] = [ + s + for s in json_schema.get("anyOf", []) + if isinstance(s, dict) and "type" in s + ] + if any_of: + first_sub_schema = any_of[0] + return cls.__from_json_schema__(first_sub_schema) + + # Fallback to string + return cls("str") diff --git a/guardrails/classes/schema/__init__.py b/guardrails/classes/schema/__init__.py new file mode 100644 index 000000000..b85bd10f1 --- /dev/null +++ b/guardrails/classes/schema/__init__.py @@ -0,0 +1,3 @@ +from guardrails.classes.schema.processed_schema import ProcessedSchema + +__all__ = ["ProcessedSchema"] diff --git a/guardrails/classes/schema/model_schema.py b/guardrails/classes/schema/model_schema.py new file mode 100644 index 000000000..cb28770ee --- /dev/null +++ b/guardrails/classes/schema/model_schema.py @@ -0,0 +1,28 @@ +from typing import Any, Dict, Optional +from guardrails_api_client import ModelSchema as IModelSchema, ValidationType + + +# Because pydantic insists on including None values in the serialized dictionary +class ModelSchema(IModelSchema): + def to_dict(self) -> Dict[str, Any]: + super_dict = super().to_dict() + return {k: v for k, v in super_dict.items() if v is not None} + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> "ModelSchema": + if not obj: + obj = {"type": "string"} + + i_model_schema = super().from_dict(obj) + + i_model_schema_dict = ( + i_model_schema.to_dict() if i_model_schema else {"type": "string"} + ) + + trimmed = {k: v for k, v in i_model_schema_dict.items() if v is not None} + + output_schema_type = trimmed.get("type") + if output_schema_type: + trimmed["type"] = ValidationType.from_dict(output_schema_type) # type: ignore + + return cls(**trimmed) # type: ignore diff --git a/guardrails/classes/schema/processed_schema.py b/guardrails/classes/schema/processed_schema.py new file mode 100644 index 000000000..5e23544d0 --- /dev/null +++ b/guardrails/classes/schema/processed_schema.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass, field +from typing import Any, Dict, List +from guardrails_api_client import ValidatorReference +from guardrails.classes.execution.guard_execution_options import GuardExecutionOptions +from guardrails.classes.output_type import OutputTypes +from guardrails.types.validator import ValidatorMap + + +@dataclass +class ProcessedSchema: + """This class is just a container for the various pieces of information we + extract from the various schema wrappers a user can pass in; i.e. RAIL or + Pydantic.""" + + output_type: OutputTypes = field(default=OutputTypes.STRING) + validators: List[ValidatorReference] = field(default_factory=list) + validator_map: ValidatorMap = field(default_factory=dict) + json_schema: Dict[str, Any] = field(default_factory=dict) + exec_opts: GuardExecutionOptions = field(default_factory=GuardExecutionOptions) diff --git a/guardrails/classes/templating/constants_container.py b/guardrails/classes/templating/constants_container.py new file mode 100644 index 000000000..599aa6b6b --- /dev/null +++ b/guardrails/classes/templating/constants_container.py @@ -0,0 +1,64 @@ +import os +from lxml import etree as ET + + +class ConstantsContainer: + def __init__(self): + self._constants = {} + self.fill_constants() + + def fill_constants(self) -> None: + self_file_path = os.path.dirname(__file__) + self_dirname = os.path.dirname(self_file_path) + constants_file = os.path.abspath( + os.path.join(self_dirname, "..", "constants.xml") + ) + + with open(constants_file, "r") as f: + xml = f.read() + + parser = ET.XMLParser(encoding="utf-8", resolve_entities=False) + parsed_constants = ET.fromstring(xml, parser=parser) + + for child in parsed_constants: + if isinstance(child, ET._Comment): + continue + if isinstance(child, str): + continue + + constant_name = child.tag + constant_value = child.text + self._constants[constant_name] = constant_value + + def __getitem__(self, key): + return self._constants[key] + + def __setitem__(self, key, value): + self._constants[key] = value + + def __delitem__(self, key): + del self._constants[key] + + def __iter__(self): + return iter(self._constants) + + def __len__(self): + return len(self._constants) + + def __contains__(self, key): + return key in self._constants + + def __repr__(self): + return repr(self._constants) + + def __str__(self): + return str(self._constants) + + def items(self): + return self._constants.items() + + def keys(self): + return self._constants.keys() + + def values(self): + return self._constants.values() diff --git a/guardrails/namespace_template.py b/guardrails/classes/templating/namespace_template.py similarity index 100% rename from guardrails/namespace_template.py rename to guardrails/classes/templating/namespace_template.py diff --git a/guardrails/classes/validation/validation_result.py b/guardrails/classes/validation/validation_result.py new file mode 100644 index 000000000..18e6a0baa --- /dev/null +++ b/guardrails/classes/validation/validation_result.py @@ -0,0 +1,181 @@ +from typing import Any, Dict, List, Literal, Optional, Union +from pydantic import Field +from guardrails_api_client import ( + ValidationResult as IValidationResult, # noqa + PassResult as IPassResult, + FailResult as IFailResult, + ErrorSpan as IErrorSpan, +) +from guardrails.classes.generic.arbitrary_model import ArbitraryModel + + +class ValidationResult(IValidationResult, ArbitraryModel): + """ValidationResult is the output type of Validator.validate and the + abstract base class for all validation results. + + Attributes: + outcome (str): The outcome of the validation. Must be one of "pass" or "fail". + metadata (Optional[Dict[str, Any]]): The metadata associated with this + validation result. + validated_chunk (Optional[Any]): The value argument passed to + validator.validate or validator.validate_stream. + """ + + outcome: str + metadata: Optional[Dict[str, Any]] = None + validated_chunk: Optional[Any] = None + + @classmethod + def from_interface( + cls, i_validation_result: Union[IValidationResult, IPassResult, IFailResult] + ) -> "ValidationResult": + if i_validation_result.outcome == "pass": + return PassResult( + outcome=i_validation_result.outcome, + metadata=i_validation_result.metadata, + validated_chunk=i_validation_result.validated_chunk, + ) + elif i_validation_result.outcome == "fail": + return FailResult.from_dict(i_validation_result.to_dict()) + + return cls( + outcome=i_validation_result.outcome or "", + metadata=i_validation_result.metadata, + validated_chunk=i_validation_result.validated_chunk, + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "ValidationResult": + i_validation_result = IValidationResult.from_dict(obj) or IValidationResult( + outcome="pail" + ) + return cls.from_interface(i_validation_result) + + +class PassResult(ValidationResult, IPassResult): + """PassResult is the output type of Validator.validate when validation + succeeds. + + Attributes: + outcome (Literal["pass"]): The outcome of the validation. Must be "pass". + value_override (Optional[Any]): The value to use as an override + if validation passes. + """ + + outcome: Literal["pass"] = "pass" + + class ValueOverrideSentinel: + pass + + # should only be used if Validator.override_value_on_pass is True + value_override: Optional[Any] = Field(default=ValueOverrideSentinel) + + def to_interface(self) -> IPassResult: + i_pass_result = IPassResult(outcome=self.outcome, metadata=self.metadata) + + if self.value_override is not self.ValueOverrideSentinel: + i_pass_result.value_override = self.value_override + + return i_pass_result + + def to_dict(self) -> Dict[str, Any]: + # Pydantic's model_dump method isn't working properly + _dict = { + "outcome": self.outcome, + "metadata": self.metadata, + "validatedChunk": self.validated_chunk, + "valueOverride": ( + self.value_override + if self.value_override is not self.ValueOverrideSentinel + else None + ), + } + return _dict + + +class FailResult(ValidationResult, IFailResult): + """FailResult is the output type of Validator.validate when validation + fails. + + Attributes: + outcome (Literal["fail"]): The outcome of the validation. Must be "fail". + error_message (str): The error message indicating why validation failed. + fix_value (Optional[Any]): The auto-fix value that would be applied + if the Validator's on_fail method is "fix". + error_spans (Optional[List[ErrorSpan]]): Segments that caused + validation to fail. + """ + + outcome: Literal["fail"] = "fail" + + error_message: str + fix_value: Optional[Any] = None + """Segments that caused validation to fail. + + May not exist for non-streamed output. + """ + error_spans: Optional[List["ErrorSpan"]] = None + + @classmethod + def from_interface(cls, i_fail_result: IFailResult) -> "FailResult": + error_spans = None + if i_fail_result.error_spans: + error_spans = [ + ErrorSpan( + start=error_span.start, + end=error_span.end, + reason=error_span.reason, + ) + for error_span in i_fail_result.error_spans + ] + + return cls( + outcome="fail", + metadata=i_fail_result.metadata, + validated_chunk=i_fail_result.validated_chunk, + error_message=i_fail_result.error_message or "", + fix_value=i_fail_result.fix_value, + error_spans=error_spans, + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "FailResult": + i_fail_result = IFailResult.from_dict(obj) or IFailResult( + outcome="Fail", + error_message="", # type: ignore - pyright doesn't understand aliases + ) + return cls.from_interface(i_fail_result) + + def to_dict(self) -> Dict[str, Any]: + # Pydantic's model_dump method isn't working properly + _dict = { + "outcome": self.outcome, + "metadata": self.metadata, + "validatedChunk": self.validated_chunk, + "errorMessage": self.error_message, + "fixValue": self.fix_value, + "errorSpans": ( + [error_span.to_dict() for error_span in self.error_spans] + if self.error_spans + else [] + ), + } + return _dict + + +class ErrorSpan(IErrorSpan, ArbitraryModel): + """ErrorSpan provide additional context for why a validation failed. They + specify the start and end index of the segment that caused the failure, + which can be useful when validating large chunks of text or validating + while streaming with different chunking methods. + + Attributes: + start (int): Starting index relative to the validated chunk. + end (int): Ending index relative to the validated chunk. + reason (str): Reason validation failed for this chunk. + """ + + start: int + end: int + # reason validation failed, specific to this chunk + reason: str diff --git a/guardrails/classes/validation/validator_logs.py b/guardrails/classes/validation/validator_logs.py new file mode 100644 index 000000000..4385b9ed2 --- /dev/null +++ b/guardrails/classes/validation/validator_logs.py @@ -0,0 +1,105 @@ +from datetime import datetime +from typing import Any, Dict, Optional + +from guardrails_api_client import ( + ValidatorLog as IValidatorLog, + ValidatorLogInstanceId, + ValidatorLogValidationResult, +) +from guardrails.classes.generic.arbitrary_model import ArbitraryModel +from guardrails.classes.validation.validation_result import ValidationResult +from guardrails.utils.casting_utils import to_int + + +class ValidatorLogs(IValidatorLog, ArbitraryModel): + """Logs for a single validator execution. + + Attributes: + validator_name (str): The class name of the validator + registered_name (str): The snake_cased id of the validator + property_path (str): The JSON path to the property being validated + value_before_validation (Any): The value before validation + value_after_validation (Optional[Any]): The value after validation; + could be different if `value_override`s or `fix`es are applied + validation_result (Optional[ValidationResult]): The result of the validation + start_time (Optional[datetime]): The time the validation started + end_time (Optional[datetime]): The time the validation ended + instance_id (Optional[int]): The unique id of this instance of the validator + """ + + validator_name: str + registered_name: str + value_before_validation: Any + validation_result: Optional[ValidationResult] = None + value_after_validation: Optional[Any] = None + start_time: Optional[datetime] = None + end_time: Optional[datetime] = None + instance_id: Optional[int] = None + property_path: str + + def to_interface(self) -> IValidatorLog: + start_time = self.start_time.isoformat() if self.start_time else None + end_time = self.end_time.isoformat() if self.end_time else None + validation_result = ( + ValidatorLogValidationResult(self.validation_result) + if self.validation_result + else None + ) + # pyright doesn't understand aliases so all type aliases are ignored. + return IValidatorLog( + validator_name=self.validator_name, # type: ignore + registered_name=self.registered_name, # type: ignore + instance_id=ValidatorLogInstanceId(self.instance_id), # type: ignore + property_path=self.property_path, # type: ignore + value_before_validation=self.value_before_validation, # type: ignore + value_after_validation=self.value_after_validation, # type: ignore + validation_result=validation_result, # type: ignore + start_time=start_time, # type: ignore + end_time=end_time, # type: ignore + ) + + def to_dict(self) -> Dict[str, Any]: + return self.to_interface().to_dict() + + @classmethod + def from_interface(cls, i_validator_log: IValidatorLog) -> "ValidatorLogs": + instance_id = ( + i_validator_log.instance_id.actual_instance + if i_validator_log.instance_id + else None + ) + validation_result = ( + ValidationResult.from_interface( + i_validator_log.validation_result.actual_instance + ) + if ( + i_validator_log.validation_result + and i_validator_log.validation_result.actual_instance + ) + else None + ) + + start_time = i_validator_log.start_time + if isinstance(start_time, str): + start_time = datetime.fromisoformat(start_time) + + end_time = i_validator_log.end_time + if isinstance(end_time, str): + end_time = datetime.fromisoformat(end_time) + + return cls( + validator_name=i_validator_log.validator_name, + registered_name=i_validator_log.registered_name, + instance_id=to_int(instance_id) or 0, + property_path=i_validator_log.property_path, + value_before_validation=i_validator_log.value_before_validation, + value_after_validation=i_validator_log.value_after_validation, + validation_result=validation_result, + start_time=start_time, + end_time=end_time, + ) + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> "ValidatorLogs": + i_validator_log = IValidatorLog.from_dict(obj) + return cls.from_interface(i_validator_log) # type: ignore diff --git a/guardrails/classes/validation/validator_reference.py b/guardrails/classes/validation/validator_reference.py new file mode 100644 index 000000000..93890d0b0 --- /dev/null +++ b/guardrails/classes/validation/validator_reference.py @@ -0,0 +1,19 @@ +from guardrails_api_client import ValidatorReference as IValidatorReference + + +# Docs only +class ValidatorReference(IValidatorReference): + """ValidatorReference is a serialized reference for constructing a + Validator. + + Attributes: + id (Optional[str]): The unique identifier for this Validator. + Often the hub id; e.g. guardrails/regex_match. Default None. + on (Optional[str]): A reference to the property this validator should be + applied against. Can be a valid JSON path or a meta-property + such as `prompt` or `output`. Default None. + on_fail (Optional[str]): The OnFailAction to apply during validation. + Default None. + args (Optional[List[Any]]): Positional arguments. Default None. + kwargs (Optional[Dict[str, Any]]): Keyword arguments. Default None. + """ diff --git a/guardrails/classes/validation_outcome.py b/guardrails/classes/validation_outcome.py index c59eadf2d..39f26a363 100644 --- a/guardrails/classes/validation_outcome.py +++ b/guardrails/classes/validation_outcome.py @@ -3,14 +3,34 @@ from pydantic import Field from rich.pretty import pretty_repr +from guardrails_api_client import ( + ValidationOutcome as IValidationOutcome, + ValidationOutcomeValidatedOutput, +) +from guardrails.actions.reask import ReAsk from guardrails.classes.history import Call, Iteration from guardrails.classes.output_type import OT +from guardrails.classes.generic.arbitrary_model import ArbitraryModel from guardrails.constants import pass_status -from guardrails.utils.logs_utils import ArbitraryModel -from guardrails.utils.reask_utils import ReAsk +from guardrails.utils.safe_get import safe_get -class ValidationOutcome(ArbitraryModel, Generic[OT]): +class ValidationOutcome(IValidationOutcome, ArbitraryModel, Generic[OT]): + """The final output from a Guard execution. + + Attributes: + call_id: The id of the Call that produced this ValidationOutcome. + raw_llm_output: The raw, unchanged output from the LLM call. + validated_output: The validated, and potentially fixed, output from the LLM call + after passing through validation. + reask: If validation continuously fails and all allocated reasks are used, + this field will contain the final reask that would have been sent + to the LLM if additional reasks were available. + validation_passed: A boolean to indicate whether or not the LLM output + passed validation. If this is False, the validated_output may be invalid. + error: If the validation failed, this field will contain the error message + """ + raw_llm_output: Optional[str] = Field( description="The raw, unchanged output from the LLM call.", default=None ) @@ -50,13 +70,16 @@ class ValidationOutcome(ArbitraryModel, Generic[OT]): @classmethod def from_guard_history(cls, call: Call): """Create a ValidationOutcome from a history Call object.""" - last_iteration = call.iterations.last or Iteration() - last_output = last_iteration.validation_response or last_iteration.parsed_output + last_iteration = call.iterations.last or Iteration(call_id=call.id, index=0) + last_output = last_iteration.validation_response or safe_get( + list(last_iteration.reasks), 0 + ) validation_passed = call.status == pass_status reask = last_output if isinstance(last_output, ReAsk) else None error = call.error output = cast(OT, call.guarded_output) return cls( + call_id=call.id, # type: ignore raw_llm_output=call.raw_outputs.last, validated_output=output, reask=reask, @@ -87,3 +110,15 @@ def __getitem__(self, keys): def __str__(self) -> str: return pretty_repr(self) + + def to_dict(self): + i_validation_outcome = IValidationOutcome( + call_id=self.call_id, # type: ignore + raw_llm_output=self.raw_llm_output, # type: ignore + validated_output=ValidationOutcomeValidatedOutput(self.validated_output), # type: ignore + reask=self.reask, + validation_passed=self.validation_passed, # type: ignore + error=self.error, + ) + + return i_validation_outcome.to_dict() diff --git a/guardrails/cli/__init__.py b/guardrails/cli/__init__.py index f1b21618b..73bc8bfe9 100644 --- a/guardrails/cli/__init__.py +++ b/guardrails/cli/__init__.py @@ -1,7 +1,11 @@ import guardrails.cli.configure # noqa +import guardrails.cli.start # noqa import guardrails.cli.validate # noqa +from guardrails.cli.create import create_command # noqa: F401 from guardrails.cli.guardrails import guardrails as cli from guardrails.cli.hub import hub_command +from guardrails.cli.watch import watch_command # noqa: F401 + cli.add_typer( hub_command, name="hub", help="Manage validators installed from the Guardrails Hub." diff --git a/guardrails/cli/configure.py b/guardrails/cli/configure.py index 2a7354892..c01fc5523 100644 --- a/guardrails/cli/configure.py +++ b/guardrails/cli/configure.py @@ -4,33 +4,40 @@ from os.path import expanduser from typing import Optional -from guardrails.classes.credentials import Credentials -from guardrails.cli.server.hub_client import AuthenticationError, get_auth import typer +from guardrails.classes.credentials import Credentials from guardrails.cli.guardrails import guardrails from guardrails.cli.logger import LEVELS, logger +from guardrails.cli.hub.console import console +from guardrails.cli.server.hub_client import AuthenticationError, get_auth DEFAULT_TOKEN = "" DEFAULT_ENABLE_METRICS = True +DEFAULT_USE_REMOTE_INFERENCING = True def save_configuration_file( - token: Optional[str], enable_metrics: Optional[bool] + token: Optional[str], + enable_metrics: Optional[bool], + use_remote_inferencing: Optional[bool] = DEFAULT_USE_REMOTE_INFERENCING, ) -> None: if token is None: token = DEFAULT_TOKEN if enable_metrics is None: enable_metrics = DEFAULT_ENABLE_METRICS + if use_remote_inferencing is None: + use_remote_inferencing = DEFAULT_USE_REMOTE_INFERENCING home = expanduser("~") guardrails_rc = os.path.join(home, ".guardrailsrc") - with open(guardrails_rc, "w") as rc_file: + with open(guardrails_rc, "w", encoding="utf-8") as rc_file: lines = [ f"id={str(uuid.uuid4())}{os.linesep}", f"token={token}{os.linesep}", - f"enable_metrics={str(enable_metrics).lower()}", + f"enable_metrics={str(enable_metrics).lower()}{os.linesep}", + f"use_remote_inferencing={str(use_remote_inferencing).lower()}", ] rc_file.writelines(lines) rc_file.close() @@ -46,38 +53,62 @@ def _get_default_token() -> str: @guardrails.command() def configure( - token: Optional[str] = typer.Option( - default_factory=_get_default_token, - help="Your Guardrails Hub auth token.", - hide_input=True, - prompt="Token (optional)", - ), enable_metrics: Optional[bool] = typer.Option( DEFAULT_ENABLE_METRICS, "--enable-metrics/--disable-metrics", help="Opt out of anonymous metrics collection.", prompt="Enable anonymous metrics reporting?", ), + token: Optional[str] = typer.Option( + None, + "--token", + help="API Key for Guardrails. If not provided, you will be prompted for it.", + ), + remote_inferencing: Optional[bool] = typer.Option( + DEFAULT_USE_REMOTE_INFERENCING, + "--enable-remote-inferencing/--disable-remote-inferencing", + help="Opt in to remote inferencing. " + "If not provided, you will be prompted for it.", + prompt="Do you wish to use remote inferencing?", + ), clear_token: Optional[bool] = typer.Option( False, "--clear-token", help="Clear the existing token from the configuration file.", ), ): - if clear_token is True: - token = DEFAULT_TOKEN + existing_token = _get_default_token() + last4 = existing_token[-4:] if existing_token else "" + + if not clear_token and token is None: + console.print("\nEnter API Key below", style="bold", end=" ") + + if last4: + console.print( + "[dim]leave empty if you want to keep existing token[/dim]", + style="italic", + end=" ", + ) + console.print(f"[{last4}]", style="italic") + + console.print( + ":backhand_index_pointing_right: You can find your API Key at https://hub.guardrailsai.com/keys" + ) + + token = typer.prompt("\nAPI Key", existing_token, show_default=False) + + else: + token = token or DEFAULT_TOKEN + try: - save_configuration_file(token, enable_metrics) + save_configuration_file(token, enable_metrics, remote_inferencing) logger.info("Configuration saved.") - - if not token: - logger.info("No token provided. Skipping authentication.") except Exception as e: - logger.error("An unexpected error occured!") + logger.error("An unexpected error occured saving configuration!") logger.error(e) sys.exit(1) - # Authenticate with the Hub if token is not empty + # Authenticate with the Hub if token is not empty if token != "" and token is not None: logger.info("Validating credentials...") try: @@ -98,3 +129,5 @@ def configure( logger.error(e) # We do not want to exit the program if the user fails to authenticate # instead, save the token and other configuration options + else: + logger.info("No token provided. Skipping authentication.") diff --git a/guardrails/cli/create.py b/guardrails/cli/create.py new file mode 100644 index 000000000..353c0f401 --- /dev/null +++ b/guardrails/cli/create.py @@ -0,0 +1,164 @@ +import os +import sys +import time +from typing import List, Optional, Union + +import typer +from rich.console import Console +from rich.syntax import Syntax + +from guardrails.cli.guardrails import guardrails as gr_cli +from guardrails.cli.hub.install import ( # JC: I don't like this import. Move fns? + install_hub_module, + add_to_hub_inits, + run_post_install, +) +from guardrails.cli.hub.utils import get_site_packages_location +from guardrails.cli.server.hub_client import get_validator_manifest + + +console = Console() + + +@gr_cli.command(name="create") +def create_command( + validators: str = typer.Option( + default="", + help="A comma-separated list of validator hub URIs.", + ), + name: Optional[str] = typer.Option( + default=None, help="The name of the guard to define in the file." + ), + filepath: str = typer.Option( + default="config.py", + help="The path to which the configuration file should be saved.", + ), + dry_run: bool = typer.Option( + default=False, + is_flag=True, + help="Print out the validators to be installed without making any changes.", + ), +): + filepath = check_filename(filepath) + installed_validators = split_and_install_validators(validators, dry_run) + new_config_file = generate_config_file(installed_validators, name) + if dry_run: + console.print(f"Not actually saving output to [bold]{filepath}[/bold]") + console.print("The following would have been written:\n") + formatted = Syntax(new_config_file, "python") + console.print(formatted) + console.print("\n") + else: + with open(filepath, "wt") as fout: + fout.write(new_config_file) + console.print(f"Saved configuration to {filepath}") + console.print( + f"Replace TODOs in {filepath} and run with `guardrails start" + f" --config {filepath}`" + ) + + +def check_filename(filename: Union[str, os.PathLike]) -> str: + """If a filename is specified and already exists, will prompt the user to + confirm overwriting. + + Aborts if the user declines. + """ + if os.path.exists(filename): + # Alert the user and get confirmation of overwrite. + overwrite = typer.confirm( + f"The configuration file {filename} already exists. Overwrite?" + ) + if not overwrite: + console.print("Aborting") + typer.Abort() + sys.exit(0) # Force exit if we fall through. + return filename # type: ignore + + +def split_and_install_validators(validators: str, dry_run: bool = False): + """Given a comma-separated list of validators, check the hub to make sure + all of them exist, install them, and return a list of 'imports'. + + If validators is empty, returns an empty list. + """ + if not validators: + return [] + + stripped_validators = list() + manifests = list() + site_packages = get_site_packages_location() + + # Split by comma, strip start and end spaces, then make sure there's a hub prefix. + # If all that passes, download the manifest file so we know where to install. + # hub://blah -> blah, then download the manifest. + console.print("Checking validators...") + with console.status("Checking validator manifests") as status: + for v in validators.split(","): + v = v.strip() + status.update(f"Prefetching {v}") + if not v.startswith("hub://"): + console.print( + f"WARNING: Validator {v} does not appear to be a valid URI." + ) + sys.exit(-1) + stripped_validator = v.lstrip("hub://") + stripped_validators.append(stripped_validator) + manifests.append(get_validator_manifest(stripped_validator)) + console.print("Success!") + + # We should make sure they exist. + console.print("Installing...") + with console.status("Installing validators") as status: + for manifest, validator in zip(manifests, stripped_validators): + status.update(f"Installing {validator}") + if not dry_run: + install_hub_module(manifest, site_packages, quiet=True) + run_post_install(manifest, site_packages) + add_to_hub_inits(manifest, site_packages) + else: + console.print(f"Fake installing {validator}") + time.sleep(1) + console.print("Success!") + + # Pull the hub information from each of the installed validators and return it. + return [manifest.exports[0] for manifest in manifests] + + +def generate_config_file(validators: List[str], name: Optional[str] = None) -> str: + console.print("Generating config file...") + config_lines = [ + "from guardrails import Guard", + ] + + # Import one or more validators. + if len(validators) == 1: + config_lines.append(f"from guardrails.hub import {validators[0]}") + elif len(validators) > 1: + multiline_import = ",\n\t".join(validators) + config_lines.append(f"from guardrails.hub import (\n\t{multiline_import}\n)") + + # Initialize our guard. + config_lines.append("guard = Guard()") + if name is not None: + config_lines.append(f"guard.name = {name.__repr__()}") + + # Warn the user that they need to update their config file. + config_lines.append( + 'print("GUARD PARAMETERS UNFILLED! UPDATE THIS FILE!")' + " # TODO: Remove this when parameters are filled." + ) + + # Append validators: + if len(validators) == 1: + config_lines.append(f"guard.use({validators[0]}()) # TODO: Add parameters.") + elif len(validators) > 1: + multi_use = "".join( + [ + "\t" + validator + "(), # TODO: Add parameters.\n" + for validator in validators + ] + ) + config_lines.append(f"guard.use_many(\n{multi_use})") + + return "\n".join(config_lines) diff --git a/guardrails/cli/hub/install.py b/guardrails/cli/hub/install.py index 931b2383f..9777269a4 100644 --- a/guardrails/cli/hub/install.py +++ b/guardrails/cli/hub/install.py @@ -1,7 +1,7 @@ -from contextlib import contextmanager import os import subprocess import sys +from contextlib import contextmanager from string import Template from typing import List, Literal @@ -9,14 +9,17 @@ from guardrails.classes.generic import Stack from guardrails.cli.hub.hub import hub_command + +from guardrails.cli.hub.utils import ( + get_hub_directory, + get_org_and_package_dirs, + get_site_packages_location, + pip_process, +) from guardrails.cli.logger import LEVELS, logger from guardrails.cli.server.hub_client import get_validator_manifest from guardrails.cli.server.module_manifest import ModuleManifest - -from guardrails.cli.hub.utils import pip_process -from guardrails.cli.hub.utils import get_site_packages_location -from guardrails.cli.hub.utils import get_org_and_package_dirs -from guardrails.cli.hub.utils import get_hub_directory +from guardrails.classes.credentials import Credentials from .console import console @@ -84,7 +87,6 @@ def add_to_hub_inits(manifest: ModuleManifest, site_packages: str): def run_post_install(manifest: ModuleManifest, site_packages: str): org_package = get_org_and_package_dirs(manifest) post_install_script = manifest.post_install - if not post_install_script: return @@ -194,6 +196,11 @@ def install( help="URI to the package to install.\ Example: hub://guardrails/regex_match." ), + local_models: bool = typer.Option( + False, + "--install-local-models/--no-install-local-models", + help="Install local models", + ), quiet: bool = typer.Option( False, "--quiet", @@ -207,6 +214,8 @@ def install( logger.error("Invalid URI!") sys.exit(1) + has_rc_file = Credentials.has_rc_file() + installing_msg = f"Installing {package_uri}..." logger.log( level=LEVELS.get("SPAM"), # type: ignore @@ -237,11 +246,39 @@ def do_nothing_context(*args, **kwargs): with loader(dl_deps_msg, spinner="bouncingBar"): install_hub_module(module_manifest, site_packages, quiet=quiet) + install_local_models = local_models + + try: + if has_rc_file: + # if we do want to remote then we don't want to install local models + install_local_models = not Credentials.from_rc_file( + logger + ).use_remote_inferencing + elif module_manifest.tags and module_manifest.tags.has_guardrails_endpoint: + install_local_models = typer.confirm( + "This validator has a Guardrails AI inference endpoint available. " + "Would you still like to install the" + " local models for local inference?", + ) + except AttributeError: + pass + # Post-install - post_msg = "Running post-install setup" - with loader(post_msg, spinner="bouncingBar"): - run_post_install(module_manifest, site_packages) - add_to_hub_inits(module_manifest, site_packages) + if install_local_models: + logger.log( + level=LEVELS.get("SPAM"), # type: ignore + msg="Installing models locally!", + ) + post_msg = "Running post-install setup" + with loader(post_msg, spinner="bouncingBar"): + run_post_install(module_manifest, site_packages) + else: + logger.log( + level=LEVELS.get("SPAM"), # type: ignore + msg="Skipping post install, models will not be " + "downloaded for local inference.", + ) + add_to_hub_inits(module_manifest, site_packages) logger.info("Installation complete") diff --git a/guardrails/cli/hub/submit.py b/guardrails/cli/hub/submit.py index 429fd2d99..4066a62cb 100644 --- a/guardrails/cli/hub/submit.py +++ b/guardrails/cli/hub/submit.py @@ -20,7 +20,7 @@ def submit( """Submit a validator to the Guardrails AI team for review and publishing.""" try: - if not filepath or filepath == "./{validator_name}.py": + if not filepath or filepath == "./{package_name}.py": filepath = f"./{package_name}.py" target = os.path.abspath(filepath) diff --git a/guardrails/cli/server/hub_client.py b/guardrails/cli/server/hub_client.py index d29bf2781..876bc5ac9 100644 --- a/guardrails/cli/server/hub_client.py +++ b/guardrails/cli/server/hub_client.py @@ -1,16 +1,19 @@ import sys +import os +from importlib.metadata import version from string import Template from typing import Any, Dict, Optional import requests -from jwt import JWT -from jwt.exceptions import JWTDecodeError +import jwt +from jwt import ExpiredSignatureError, DecodeError + from guardrails.classes.credentials import Credentials from guardrails.cli.logger import logger from guardrails.cli.server.module_manifest import ModuleManifest -FIND_NEW_TOKEN = "You can find a new token at https://hub.guardrailsai.com/tokens" +FIND_NEW_TOKEN = "You can find a new token at https://hub.guardrailsai.com/keys" TOKEN_EXPIRED_MESSAGE = f"""Your token has expired. Please run `guardrails configure`\ to update your token. @@ -18,8 +21,11 @@ TOKEN_INVALID_MESSAGE = f"""Your token is invalid. Please run `guardrails configure`\ to update your token. {FIND_NEW_TOKEN}""" +GUARDRAILS_VERSION = version("guardrails-ai") -validator_hub_service = "https://so4sg4q4pb.execute-api.us-east-1.amazonaws.com" +VALIDATOR_HUB_SERVICE = os.getenv( + "GR_VALIDATOR_HUB_SERVICE", "https://so4sg4q4pb.execute-api.us-east-1.amazonaws.com" +) validator_manifest_endpoint = Template( "validator-manifests/${namespace}/${validator_name}" ) @@ -49,6 +55,7 @@ def fetch(url: str, token: Optional[str], anonymousUserId: Optional[str]): headers = { "Authorization": f"Bearer {token}", "x-anonymous-user-id": anonymousUserId, + "x-guardrails-version": GUARDRAILS_VERSION, } req = requests.get(url, headers=headers) body = req.json() @@ -76,7 +83,7 @@ def fetch_module_manifest( manifest_path = validator_manifest_endpoint.safe_substitute( namespace=namespace, validator_name=validator_name ) - manifest_url = f"{validator_hub_service}/{manifest_path}" + manifest_url = f"{VALIDATOR_HUB_SERVICE}/{manifest_path}" return fetch(manifest_url, token, anonymousUserId) @@ -86,13 +93,11 @@ def get_jwt_token(creds: Credentials) -> Optional[str]: # check for jwt expiration if token: try: - JWT().decode(token, do_verify=False) - except JWTDecodeError as e: - # if the error message includes "Expired", then the token is expired - if "Expired" in str(e): - raise ExpiredTokenError(TOKEN_EXPIRED_MESSAGE) - else: - raise InvalidTokenError(TOKEN_INVALID_MESSAGE) + jwt.decode(token, options={"verify_signature": False, "verify_exp": True}) + except ExpiredSignatureError: + raise ExpiredTokenError(TOKEN_EXPIRED_MESSAGE) + except DecodeError: + raise InvalidTokenError(TOKEN_INVALID_MESSAGE) return token @@ -128,7 +133,7 @@ def get_auth(): try: creds = Credentials.from_rc_file(logger) token = get_jwt_token(creds) - auth_url = f"{validator_hub_service}/auth" + auth_url = f"{VALIDATOR_HUB_SERVICE}/auth" response = fetch(auth_url, token, creds.id) if not response: raise AuthenticationError("Failed to authenticate!") @@ -146,7 +151,7 @@ def post_validator_submit(package_name: str, content: str): try: creds = Credentials.from_rc_file(logger) token = get_jwt_token(creds) - submission_url = f"{validator_hub_service}/validator/submit" + submission_url = f"{VALIDATOR_HUB_SERVICE}/validator/submit" headers = { "Authorization": f"Bearer {token}", diff --git a/guardrails/cli/server/module_manifest.py b/guardrails/cli/server/module_manifest.py index 61a5c7ccf..34e36d820 100644 --- a/guardrails/cli/server/module_manifest.py +++ b/guardrails/cli/server/module_manifest.py @@ -26,6 +26,7 @@ class ModuleTags(Serializeable): content_type: Optional[List[str]] = field(default_factory=list) validation_category: Optional[List[str]] = field(default_factory=list) process_requirements: Optional[List[str]] = field(default_factory=list) + has_guardrails_endpoint: Optional[bool] = field(default_factory=bool) @dataclass diff --git a/guardrails/cli/start.py b/guardrails/cli/start.py new file mode 100644 index 000000000..5d5530abe --- /dev/null +++ b/guardrails/cli/start.py @@ -0,0 +1,41 @@ +from typing import Optional +import typer + +from guardrails.cli.guardrails import guardrails +from guardrails.cli.hub.utils import pip_process +from guardrails.cli.logger import logger + + +def api_is_installed() -> bool: + try: + import guardrails_api # type: ignore # noqa + + return True + except ImportError: + return False + + +@guardrails.command() +def start( + env: Optional[str] = typer.Option( + default="", + help="An env file to load environment variables from.", + ), + config: Optional[str] = typer.Option( + default="", + help="A config file to load Guards from.", + ), + port: Optional[int] = typer.Option( + default=8000, + help="The port to run the server on.", + ), +): + logger.debug("Checking for prerequisites...") + if not api_is_installed(): + package_name = 'guardrails-api>="^0.0.0a0"' + pip_process("install", package_name) + + from guardrails_api.cli.start import start # type: ignore + + logger.info("Starting Guardrails server") + start(env, config, port) diff --git a/guardrails/cli/watch.py b/guardrails/cli/watch.py new file mode 100644 index 000000000..ba163b976 --- /dev/null +++ b/guardrails/cli/watch.py @@ -0,0 +1,60 @@ +import json +import sqlite3 +import time +from dataclasses import asdict +from typing import Optional + +import rich +import typer + +from guardrails.cli.guardrails import guardrails as gr_cli +from guardrails.call_tracing import GuardTraceEntry, TraceHandler + + +@gr_cli.command(name="watch") +def watch_command( + plain: bool = typer.Option( + default=False, + is_flag=True, + help="Do not use any rich formatting, instead printing each entry on a line.", + ), + num_lines: int = typer.Option( + default=0, + help="Print the last n most recent lines. If omitted, will print all history.", + ), + follow: bool = typer.Option( + default=True, + help="Continuously read the last output commands", + ), + log_path_override: Optional[str] = typer.Option( + default=None, help="Specify a path to the log output file." + ), +): + # Open a reader for the log path: + log_reader = None + while log_reader is None: + try: + if log_path_override is not None: + log_reader = TraceHandler.get_reader(log_path_override) # type: ignore + else: + log_reader = TraceHandler.get_reader() + except sqlite3.OperationalError: + print("Logfile not found. Retrying.") + time.sleep(1) + + # If we are using fancy outputs, grab a console ref and prep a table. + output_fn = _print_and_format_plain + if not plain: + output_fn = _print_fancy + + # Spin while tailing, breaking if we aren't continuously tailing. + for log_msg in log_reader.tail_logs(-num_lines, follow): + output_fn(log_msg) + + +def _print_fancy(log_msg: GuardTraceEntry): + rich.print(log_msg) + + +def _print_and_format_plain(log_msg: GuardTraceEntry) -> None: + print(json.dumps(asdict(log_msg))) diff --git a/guardrails/constants.xml b/guardrails/constants.xml index 55d016d4e..7af4906d6 100644 --- a/guardrails/constants.xml +++ b/guardrails/constants.xml @@ -2,24 +2,47 @@ -Return a valid JSON object that respects this XML format and extracts only the information requested in this document. Respect the types indicated in the XML -- the information you extract should be converted into the correct 'type'. Try to be as correct and concise as possible. Find all relevant information in the document. If you are unsure of the answer, enter 'None'. If you answer incorrectly, you will be asked again until you get it right which is expensive. +Return a valid JSON object that respects this JSON Schema and extracts only the information requested in this document. Respect the types indicated in the JSON Schema -- the information you extract should be converted into the correct 'type'. Try to be as correct and concise as possible. Find all relevant information in the document. If you are unsure of the answer, enter 'None'. If you answer incorrectly, you will be asked again until you get it right which is expensive. + +Return a valid JSON object that respects this XML format and extracts only the information requested in this document. Respect the types indicated in the XML -- the information you extract should be converted into the correct 'type'. Try to be as correct and concise as possible. Find all relevant information in the document. If you are unsure of the answer, enter 'None'. If you answer incorrectly, you will be asked again until you get it right which is expensive. + + Given below is XML that describes the information to extract from this document and the tags to extract it into. + +Given below is a JSON Schema that describes the output structure you should return. + + -ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter "None". +ONLY return a valid JSON object (no other text is necessary), where the key of the field in the JSON is the key of the entries within the schema's `properties`, and the value is of the type specified by the `type` property under that key. +The JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A JSON Schema ITSELF. +Be sure to include any types and format requests e.g. requests for lists, objects and specific types. +Be correct and concise. +If you are unsure anywhere, enter "None". + +ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter "None". + + -ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. +ONLY return a valid JSON object (no other text is necessary), where the key of the field in the JSON is the key of the entries within the schema's `properties`, and the value is of the type specified by the `type` property under that key. +The JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A JSON Schema ITSELF. +Be sure to include any types and format requests e.g. requests for lists, objects and specific types. +Be correct and concise. + +ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. + + I was given the following JSON response, which had problems due to incorrect values. @@ -45,68 +68,146 @@ Help me correct this by making it valid JSON. -Given below is XML that describes the information to extract from this document and the tags to extract it into. +Given below is a JSON Schema that describes the output structure you should return. ${output_schema} -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. +ONLY return a valid JSON object (no other text is necessary), where the key of the field in the JSON is the key of the entries within the schema's `properties`, and the value is of the type specified by the `type` property under that key. +The JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A JSON Schema ITSELF. +Be sure to include any types and format requests e.g. requests for lists, objects and specific types. +Be correct and concise. +If you are unsure anywhere, enter `null`. + +Given below is XML that describes the information to extract from this document and the tags to extract it into. + +${xml_output_schema} + +ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. + + ${gr.json_suffix_without_examples} Here's an example of the structure: ${json_example} + +${gr.xml_suffix_without_examples} +Here's an example of the structure: +${json_example} + + -Given below is XML that describes the information to extract from this document and the tags to extract it into. +Given below is a JSON Schema that describes the information to extract from this document and the tags to extract it into. ${output_schema} +ONLY return a valid JSON object (no other text is necessary), where the key of the field in the JSON is the key of the entries within the schema's `properties`, and the value is of the type specified by the `type` property under that key. +The JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A JSON Schema ITSELF. +Be sure to include any types and format requests e.g. requests for lists, objects and specific types. +Be correct and concise. +If you are unsure anywhere, enter `null`. + +Here are examples of simple (JSON Schema, JSON) pairs that show the expected behavior: +- `{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}` => `{'foo': 'example one'}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}}}}` => `{"bar": ['STRING ONE', 'STRING TWO']}` +- `{"type":"object","properties":{"baz":{"type":"object","properties":{"foo":{"type":"string","format":"capitalize two-words"},"index":{"type":"integer","format":"1-indexed"}}}}}` => `{'baz': {'foo': 'Some String', 'index': 1}}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}},"baz":{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}}}` => `{'bar': ['STRING ONE', 'STRING TWO'], 'baz': {'foo': 'example one'}}` + + + +Given below is XML that describes the information to extract from this document and the tags to extract it into. + +${xml_output_schema} + ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. Here are examples of simple (XML, JSON) pairs that show the expected behavior: - ``]]> => `{'foo': 'example one'}` - `]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` - `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - + -Given below is XML that describes the information to extract from this document and the tags to extract it into. +Given below is a JSON Schema that describes the information to extract from this document and the tags to extract it into. ${output_schema} +ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the JSON Schema, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. + +Here are examples of simple (JSON Schema, JSON) pairs that show the expected behavior: +- `{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}` => `{'foo': 'example one'}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}}}}` => `{"bar": ['STRING ONE', 'STRING TWO']}` +- `{"type":"object","properties":{"baz":{"type":"object","properties":{"foo":{"type":"string","format":"capitalize two-words"},"index":{"type":"integer","format":"1-indexed"}}}}}` => `{'baz': {'foo': 'Some String', 'index': 1}}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}},"baz":{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}}}` => `{'bar': ['STRING ONE', 'STRING TWO'], 'baz': {'foo': 'example one'}}` + + + +Given below is XML that describes the information to extract from this document and the tags to extract it into. + +${xml_output_schema} + ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. Here are examples of simple (XML, JSON) pairs that show the expected behavior: - ``]]> => `{'foo': 'example one'}` - `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` - `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - + -Given below is XML that describes the information to extract from this document and the tags to extract it into. +Given below is JSON Schema that describes the information to extract from this document and the tags to extract it into. ${output_schema} +ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the JSON Schema, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, try your best guess. + +Here are examples of simple (JSON Schema, JSON) pairs that show the expected behavior: +- `{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}` => `{'foo': 'example one'}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}}}}` => `{"bar": ['STRING ONE', 'STRING TWO']}` +- `{"type":"object","properties":{"baz":{"type":"object","properties":{"foo":{"type":"string","format":"capitalize two-words"},"index":{"type":"integer","format":"1-indexed"}}}}}` => `{'baz': {'foo': 'Some String', 'index': 1}}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}},"baz":{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}}}` => `{'bar': ['STRING ONE', 'STRING TWO'], 'baz': {'foo': 'example one'}}` + + + +Given below is XML that describes the information to extract from this document and the tags to extract it into. + +${xml_output_schema} + ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, try your best guess. Here are examples of simple (XML, JSON) pairs that show the expected behavior: - ``]]> => `{'foo': 'example one'}` - `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` - `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - + +ONLY return a valid JSON object (no other text is necessary), where the key of the field in the JSON is the key of the entries within the schema's `properties`, and the value is of the type specified by the `type` property under that key. +The JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A JSON Schema ITSELF. +Be sure to include any types and format requests e.g. requests for lists, objects and specific types. +Be correct and concise. +If you are unsure anywhere, enter `null`. + +Here are examples of simple (JSON Schema, JSON) pairs that show the expected behavior: +- `{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}` => `{'foo': 'example one'}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}}}}` => `{"bar": ['STRING ONE', 'STRING TWO']}` +- `{"type":"object","properties":{"baz":{"type":"object","properties":{"foo":{"type":"string","format":"capitalize two-words"},"index":{"type":"integer","format":"1-indexed"}}}}}` => `{'baz': {'foo': 'Some String', 'index': 1}}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}},"baz":{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}}}` => `{'bar': ['STRING ONE', 'STRING TWO'], 'baz': {'foo': 'example one'}}` + + + ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. Here are examples of simple (XML, JSON) pairs that show the expected behavior: - ``]]> => `{'foo': 'example one'}` - `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` - `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - + This was a previous response you generated: @@ -125,13 +226,32 @@ ${output_schema} You are a helpful assistant only capable of communicating with valid JSON, and no other text. +ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the JSON Schema provided, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. + +Here are examples of simple (JSON Schema, JSON) pairs that show the expected behavior: +- `{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}` => `{'foo': 'example one'}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}}}}` => `{"bar": ['STRING ONE', 'STRING TWO']}` +- `{"type":"object","properties":{"baz":{"type":"object","properties":{"foo":{"type":"string","format":"capitalize two-words"},"index":{"type":"integer","format":"1-indexed"}}}}}` => `{'baz': {'foo': 'Some String', 'index': 1}}` +- `{"type":"object","properties":{"bar":{"type":"array","items":{"type":"string","format":"upper-case"}},"baz":{"type":"object","properties":{"foo":{"type":"string","format":"two-words lower-case"}}}}}` => `{'bar': ['STRING ONE', 'STRING TWO'], 'baz': {'foo': 'example one'}}` + + + +You are a helpful assistant only capable of communicating with valid JSON, and no other text. + ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. Here are examples of simple (XML, JSON) pairs that show the expected behavior: - ``]]> => `{'foo': 'example one'}` - `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` - `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - + + + + +Error Messages: +${error_messages} + + Return a valid JSON object that respects this XML format and extracts only the information requested in this document. Respect the types indicated in the XML -- the information you extract should be converted into the correct 'type'. Try to be as correct and concise as possible. Find all relevant information in the document. If you are unsure of the answer, enter 'None'. If you answer incorrectly, you will be asked again until you get it right which is expensive. @@ -164,79 +284,4 @@ ${previous_response} Help me correct this by making it valid JSON. - -Given below is XML that describes the information to extract from this document and the tags to extract it into. - -${output_schema} - -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. - - - -${gr.xml_suffix_without_examples} -Here's an example of the structure: -${xml_example} - - - -Given below is XML that describes the information to extract from this document and the tags to extract it into. - -${output_schema} - -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. - -Here are examples of simple (XML, JSON) pairs that show the expected behavior: -- ``]]> => `{'foo': 'example one'}` -- `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` -- `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - - - -Given below is XML that describes the information to extract from this document and the tags to extract it into. - -${output_schema} - -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. - -Here are examples of simple (XML, JSON) pairs that show the expected behavior: -- ``]]> => `{'foo': 'example one'}` -- `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` -- `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - - - - -Given below is XML that describes the information to extract from this document and the tags to extract it into. - -${output_schema} - -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, try your best guess. - -Here are examples of simple (XML, JSON) pairs that show the expected behavior: -- ``]]> => `{'foo': 'example one'}` -- `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` -- `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - - - - -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. - -Here are examples of simple (XML, JSON) pairs that show the expected behavior: -- ``]]> => `{'foo': 'example one'}` -- `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` -- `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - - - -You are a helpful assistant only capable of communicating with valid JSON, and no other text. - -ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`. - -Here are examples of simple (XML, JSON) pairs that show the expected behavior: -- ``]]> => `{'foo': 'example one'}` -- `
]]>` => `{"bar": ['STRING ONE', 'STRING TWO', etc.]}` -- `
]]>` => `{'baz': {'foo': 'Some String', 'index': 1}}` - - \ No newline at end of file diff --git a/guardrails/datatypes.py b/guardrails/datatypes.py index cc117e053..eb80f68d4 100644 --- a/guardrails/datatypes.py +++ b/guardrails/datatypes.py @@ -1,662 +1,10 @@ -import datetime -from dataclasses import dataclass -from types import SimpleNamespace -from typing import Any, Dict, Iterable -from typing import List as TypedList -from typing import Optional, Sequence, Type, TypeVar, Union +from typing import List -from dateutil.parser import parse -from lxml import etree as ET -from typing_extensions import Self +from guardrails_api_client import SimpleTypes +from guardrails.types.rail import RailTypes -from guardrails.utils.casting_utils import to_float, to_int, to_string -from guardrails.utils.xml_utils import cast_xml_to_string -from guardrails.validator_base import Validator, ValidatorSpec -from guardrails.validatorsattr import ValidatorsAttr - -@dataclass -class FieldValidation: - key: Any - value: Any - validators: TypedList[Validator] - children: TypedList["FieldValidation"] - - -def verify_metadata_requirements( - metadata: dict, datatypes: Union["DataType", Iterable["DataType"]] -) -> TypedList[str]: - missing_keys = set() - if isinstance(datatypes, DataType): - datatypes = [datatypes] - for datatype in datatypes: - for validator in datatype.validators: - for requirement in validator.required_metadata_keys: - if requirement not in metadata: - missing_keys.add(requirement) - nested_missing_keys = verify_metadata_requirements( - metadata, vars(datatype.children).values() - ) - missing_keys.update(nested_missing_keys) - missing_keys = list(missing_keys) - missing_keys.sort() - return missing_keys - - -class DataType: - rail_alias: str - tag: str - - def __init__( - self, - children: Dict[str, Any], - validators_attr: ValidatorsAttr, - optional: bool, - name: Optional[str], - description: Optional[str], - ) -> None: - self._children = children - self.validators_attr = validators_attr - self.name = name - self.description = description - self.optional = optional - - def get_example(self): - raise NotImplementedError - - @property - def validators(self) -> TypedList: - return self.validators_attr.validators - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self._children})" - - def from_str(self, s: str) -> str: - """Create a DataType from a string. - - Note: ScalarTypes like int, float, bool, etc. will override this method. - Other ScalarTypes like string, email, url, etc. will not override this - """ - return s - - def _constructor_validation( - self, - key: str, - value: Any, - ) -> FieldValidation: - """Creates a "FieldValidation" object for ValidatorService to run over, - which specifies the key, value, and validators for a given field. - - Its children should be populated by its nested fields' - FieldValidations. - """ - return FieldValidation( - key=key, value=value, validators=self.validators, children=[] - ) - - def collect_validation( - self, - key: str, - value: Any, - schema: Dict, - ) -> FieldValidation: - """Gather validators on a value.""" - value = self.from_str(value) - return self._constructor_validation(key, value) - - def set_children_from_xml(self, element: ET._Element): - raise NotImplementedError("Abstract method.") - - @classmethod - def from_xml(cls, element: ET._Element, strict: bool = False, **kwargs) -> Self: - # TODO: don't want to pass strict through to DataType, - # but need to pass it to ValidatorsAttr.from_element - # how to handle this? - validators_attr = ValidatorsAttr.from_xml(element, cls.tag, strict) - - is_optional = element.attrib.get("required", "true") == "false" - - name = element.attrib.get("name") - if name is not None: - name = cast_xml_to_string(name) - - description = element.attrib.get("description") - if description is not None: - description = cast_xml_to_string(description) - - data_type = cls({}, validators_attr, is_optional, name, description, **kwargs) - data_type.set_children_from_xml(element) - return data_type - - @property - def children(self) -> SimpleNamespace: - """Return a SimpleNamespace of the children of this DataType.""" - return SimpleNamespace(**self._children) - - def __eq__(self, other): - if not isinstance(other, type(self)): - return False - return self.__dict__ == other.__dict__ - - def _to_request(self) -> Dict[str, Any]: - element: Dict[str, Any] = { - "type": self.tag, - "name": self.name, - "description": self.description, - # This isn't stored anywhere and is inconsistently passed to ValidatorsAttr - # (i.e. is never passed to child properties) - # meaning its purpose isn't consistenly enforced. - # Since this is an XML only property and isn't properly implemented anymore, - # I'm just going to ignore it for now. - "strict": False, - "onFails": [ - {"validatorTag": v.rail_alias, "method": v.on_fail_descriptor} - for v in self.validators_attr.validators - ], - "dateFormat": getattr(self, "date_format", None), - "timeFormat": getattr(self, "time_format", None), - } - formatters = [v.to_xml_attrib() for v in self.validators_attr.validators] - children: Dict[str, Any] = { - k: v._to_request() for k, v in self._children.items() - } - - return {"children": children, "formatters": formatters, "element": element} - - -registry: Dict[str, Type[DataType]] = {} - - -T = TypeVar("T", bound=Type[DataType]) - - -# Create a decorator to register a type -def register_type(name: str): - def decorator(cls: T) -> T: - registry[name] = cls - cls.rail_alias = name - return cls - - return decorator - - -class ScalarType(DataType): - def set_children_from_xml(self, element: ET._Element): - for _ in element: - raise ValueError("ScalarType data type must not have any children.") - - -class NonScalarType(DataType): - pass - - -@register_type("string") -class String(ScalarType): - """Element tag: ``""" - - tag = "string" - - def get_example(self): - return "string" - - def from_str(self, s: str) -> Optional[str]: - """Create a String from a string.""" - return to_string(s) - - @classmethod - def from_string_rail( - cls, - validators: Sequence[ValidatorSpec], - description: Optional[str] = None, - strict: bool = False, - ) -> Self: - return cls( - children={}, - validators_attr=ValidatorsAttr.from_validators(validators, cls.tag, strict), - optional=False, - name=None, - description=description, - ) - - -@register_type("integer") -class Integer(ScalarType): - """Element tag: ``""" - - tag = "integer" - - def get_example(self): - return 1 - - def from_str(self, s: str) -> Optional[int]: - """Create an Integer from a string.""" - return to_int(s) - - -@register_type("float") -class Float(ScalarType): - """Element tag: ``""" - - tag = "float" - - def get_example(self): - return 1.5 - - def from_str(self, s: str) -> Optional[float]: - """Create a Float from a string.""" - return to_float(s) - - -@register_type("bool") -class Boolean(ScalarType): - """Element tag: ``""" - - tag = "bool" - - def get_example(self): - return True - - def from_str(self, s: Union[str, bool]) -> Optional[bool]: - """Create a Boolean from a string.""" - if s is None: - return None - - if isinstance(s, bool): - return s - - if s.lower() == "true": - return True - elif s.lower() == "false": - return False - else: - raise ValueError(f"Invalid boolean value: {s}") - - -@register_type("date") -class Date(ScalarType): - """Element tag: `` - - To configure the date format, create a date-format attribute on the - element. E.g. `` - """ - - tag = "date" - - def __init__( - self, - children: Dict[str, Any], - validators_attr: "ValidatorsAttr", - optional: bool, - name: Optional[str], - description: Optional[str], - ) -> None: - super().__init__(children, validators_attr, optional, name, description) - self.date_format = None - - def get_example(self): - return datetime.date.today() - - def from_str(self, s: str) -> Optional[datetime.date]: - """Create a Date from a string.""" - if s is None: - return None - if not self.date_format: - return parse(s).date() - return datetime.datetime.strptime(s, self.date_format).date() - - @classmethod - def from_xml(cls, element: ET._Element, strict: bool = False) -> "Date": - datatype = super().from_xml(element, strict) - - if "date-format" in element.attrib or "date_format" in element.attrib: - datatype.date_format = element.attrib["date-format"] - - return datatype - - -@register_type("time") -class Time(ScalarType): - """Element tag: `