From 6ae7f75e82de6b89b67feeb436234d140ccf6006 Mon Sep 17 00:00:00 2001 From: David Tam Date: Mon, 21 Oct 2024 17:03:07 -0700 Subject: [PATCH 1/2] update validator default on fail behavior from no op to exception --- guardrails/utils/tokenization_utils.py | 8 ++---- guardrails/validator_base.py | 8 +++--- .../schema/test_primitive_schema.py | 2 +- tests/integration_tests/test_guard.py | 16 ++++++----- .../databricks/test_ml_flow_instrumentor.py | 2 +- tests/unit_tests/test_async_guard.py | 28 +++++++++---------- tests/unit_tests/test_guard.py | 22 +++++++-------- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/guardrails/utils/tokenization_utils.py b/guardrails/utils/tokenization_utils.py index 6dab87cdd..437fdb751 100644 --- a/guardrails/utils/tokenization_utils.py +++ b/guardrails/utils/tokenization_utils.py @@ -17,11 +17,9 @@ def replace_til_no_change(input_text, pattern, replacement): def postproc_splits(sentences, separator): - """ - Applies heuristic rules to repair sentence splitting errors. - Developed for use as postprocessing for the GENIA sentence - splitter on PubMed abstracts, with minor tweaks for - full-text documents. + """Applies heuristic rules to repair sentence splitting errors. Developed + for use as postprocessing for the GENIA sentence splitter on PubMed + abstracts, with minor tweaks for full-text documents. `sentences` should be a string, with line breaks on sentence boundaries. Returns a similar string, but more correct. diff --git a/guardrails/validator_base.py b/guardrails/validator_base.py index ba86d2989..1425c134b 100644 --- a/guardrails/validator_base.py +++ b/guardrails/validator_base.py @@ -49,9 +49,9 @@ def split_sentence_str(chunk: str): def split_sentence_word_tokenizers_jl_separator( chunk: str, separator: str = "abcdsentenceseperatordcba" ): - """ - Use a sentence tokenizer to detect if at least one sentence is present in the chunk. - We return the first sentence and the remaining chunks without the first sentence. + """Use a sentence tokenizer to detect if at least one sentence is present + in the chunk. We return the first sentence and the remaining chunks without + the first sentence. We perform the first step of WordTokenizers.jl's split_sentences function to detect possible sentence boundaries before calling the sentence tokenizer. @@ -142,7 +142,7 @@ def __init__( self.accumulated_chunks: List[str] = [] if on_fail is None: - on_fail = OnFailAction.NOOP + on_fail = OnFailAction.EXCEPTION if isinstance(on_fail, OnFailAction): self.on_fail_descriptor = on_fail self.on_fail_method = None diff --git a/tests/integration_tests/schema/test_primitive_schema.py b/tests/integration_tests/schema/test_primitive_schema.py index 566c6dcb0..9d8a7e27b 100644 --- a/tests/integration_tests/schema/test_primitive_schema.py +++ b/tests/integration_tests/schema/test_primitive_schema.py @@ -31,7 +31,7 @@ def test_choice_case_happy_path(self): ValidatorReference( id="valid-choices", on="$", - on_fail=OnFailAction.NOOP, + on_fail=OnFailAction.EXCEPTION, kwargs={"choices": ["north", "south", "east", "west"]}, ), ValidatorReference( diff --git a/tests/integration_tests/test_guard.py b/tests/integration_tests/test_guard.py index 7fb99b094..f8fb2f8e8 100644 --- a/tests/integration_tests/test_guard.py +++ b/tests/integration_tests/test_guard.py @@ -1270,9 +1270,9 @@ def test_guard_i_guard(self): guard = Guard( name="name-case", description="Checks that a string is in Name Case format." ).use_many( - RegexMatch(regex="^(?:[A-Z][^\s]*\s?)+$"), - ValidLength(1, 100), - ValidChoices(["Some Name", "Some Other Name"]), + RegexMatch(regex="^(?:[A-Z][^\s]*\s?)+$", on_fail="noop"), + ValidLength(1, 100, on_fail="noop"), + ValidChoices(["Some Name", "Some Other Name"], on_fail="noop"), ) response = guard.parse("Some Name") @@ -1315,9 +1315,9 @@ def test_ser_deser(self): guard = Guard( name="name-case", description="Checks that a string is in Name Case format." ).use_many( - RegexMatch(regex="^(?:[A-Z][^\s]*\s?)+$"), - ValidLength(1, 100), - ValidChoices(["Some Name", "Some Other Name"]), + RegexMatch(regex="^(?:[A-Z][^\s]*\s?)+$", on_fail="noop"), + ValidLength(1, 100, on_fail="noop"), + ValidChoices(["Some Name", "Some Other Name"], on_fail="noop"), ) response = guard.parse("Some Name") @@ -1379,7 +1379,9 @@ class TestValidatorInitializedOnce: def test_guard_init(self, mocker): init_spy = mocker.spy(LowerCase, "__init__") - guard = Guard(validators=[ValidatorReference(id="lower-case", on="$")]) + guard = Guard( + validators=[ValidatorReference(id="lower-case", on="$", onFail="noop")] + ) # Validator is not initialized until the guard is used assert init_spy.call_count == 0 diff --git a/tests/unit_tests/integrations/databricks/test_ml_flow_instrumentor.py b/tests/unit_tests/integrations/databricks/test_ml_flow_instrumentor.py index 07177dc24..25bdfd72c 100644 --- a/tests/unit_tests/integrations/databricks/test_ml_flow_instrumentor.py +++ b/tests/unit_tests/integrations/databricks/test_ml_flow_instrumentor.py @@ -625,7 +625,7 @@ def test__instrument_validator_validate(self, mocker): validator_span=mock_span, # type: ignore validator_name="mock-validator", obj_id=id(mock_validator), - on_fail_descriptor="noop", + on_fail_descriptor="exception", result=resp, init_kwargs={}, validation_session_id="unknown", diff --git a/tests/unit_tests/test_async_guard.py b/tests/unit_tests/test_async_guard.py index 0fbebbd3a..1c26b8965 100644 --- a/tests/unit_tests/test_async_guard.py +++ b/tests/unit_tests/test_async_guard.py @@ -165,12 +165,12 @@ def test_use(): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[2], LowerCase) assert ( - guard._validators[2].on_fail_descriptor == OnFailAction.NOOP + guard._validators[2].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[3], TwoWords) @@ -265,12 +265,12 @@ def test_use_many_instances(): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[2], LowerCase) assert ( - guard._validators[2].on_fail_descriptor == OnFailAction.NOOP + guard._validators[2].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[3], TwoWords) @@ -317,12 +317,12 @@ class TestClass(BaseModel): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[2], LowerCase) assert ( - guard._validators[2].on_fail_descriptor == OnFailAction.NOOP + guard._validators[2].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[3], TwoWords) @@ -385,7 +385,7 @@ def test_use_many_tuple(): assert isinstance(guard._validators[0], OneLine) assert ( - guard._validators[0].on_fail_descriptor == OnFailAction.NOOP + guard._validators[0].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[1], EndsWith) @@ -431,7 +431,7 @@ def test_use_many_tuple(): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default # Test with an unrecognized "on" parameter, should warn with a UserWarning @@ -468,11 +468,11 @@ async def test_output_only_success(self): async def test_output_only_failure(self): guard: AsyncGuard = ( AsyncGuard() - .use(OneLine) + .use(OneLine, on_fail=OnFailAction.NOOP) .use( LowerCase(on_fail=OnFailAction.FIX), on="output" ) # default on="output", still explicitly set - .use(TwoWords) + .use(TwoWords, on_fail=OnFailAction.NOOP) .use(ValidLength, 0, 12, on_fail=OnFailAction.REFRAIN) ) @@ -509,11 +509,11 @@ async def test_on_many_success(self): async def test_on_many_failure(self): guard: AsyncGuard = ( AsyncGuard() - .use(OneLine, on="messages") - .use(LowerCase, on="messages") - .use(UpperCase, on="messages") + .use(OneLine, on="messages", on_fail=OnFailAction.NOOP) + .use(LowerCase, on="messages", on_fail=OnFailAction.NOOP) + .use(UpperCase, on="messages", on_fail=OnFailAction.NOOP) .use(LowerCase, on="output", on_fail=OnFailAction.FIX) - .use(TwoWords) + .use(TwoWords, on_fail=OnFailAction.NOOP) .use(ValidLength, 0, 12, on_fail=OnFailAction.REFRAIN) ) diff --git a/tests/unit_tests/test_guard.py b/tests/unit_tests/test_guard.py index dc2ac5479..22ab2ed5c 100644 --- a/tests/unit_tests/test_guard.py +++ b/tests/unit_tests/test_guard.py @@ -213,12 +213,12 @@ def test_use(): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[2], LowerCase) assert ( - guard._validators[2].on_fail_descriptor == OnFailAction.NOOP + guard._validators[2].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[3], TwoWords) @@ -303,12 +303,12 @@ def test_use_many_instances(): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[2], LowerCase) assert ( - guard._validators[2].on_fail_descriptor == OnFailAction.NOOP + guard._validators[2].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[3], TwoWords) @@ -356,12 +356,12 @@ class TestClass(BaseModel): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[2], LowerCase) assert ( - guard._validators[2].on_fail_descriptor == OnFailAction.NOOP + guard._validators[2].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[3], TwoWords) @@ -424,7 +424,7 @@ def test_use_many_tuple(): assert isinstance(guard._validators[0], OneLine) assert ( - guard._validators[0].on_fail_descriptor == OnFailAction.NOOP + guard._validators[0].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default assert isinstance(guard._validators[1], EndsWith) @@ -470,7 +470,7 @@ def test_use_many_tuple(): assert isinstance(guard._validators[1], OneLine) assert ( - guard._validators[1].on_fail_descriptor == OnFailAction.NOOP + guard._validators[1].on_fail_descriptor == OnFailAction.EXCEPTION ) # bc this is the default # Test with an unrecognized "on" parameter, should warn with a UserWarning @@ -505,11 +505,11 @@ def test_output_only_success(self): def test_output_only_failure(self): guard: Guard = ( Guard() - .use(OneLine) + .use(OneLine, on_fail=OnFailAction.NOOP) .use( LowerCase(on_fail=OnFailAction.FIX), on="output" ) # default on="output", still explicitly set - .use(TwoWords) + .use(TwoWords, on_fail=OnFailAction.NOOP) .use(ValidLength, 0, 12, on_fail=OnFailAction.REFRAIN) ) @@ -546,7 +546,7 @@ def test_on_many_failure(self): Guard() .use(OneLine, on="messages") .use(LowerCase, on="output", on_fail=OnFailAction.FIX) - .use(TwoWords) + .use(TwoWords, on_fail=OnFailAction.NOOP) .use(ValidLength, 0, 12, on_fail=OnFailAction.REFRAIN) ) From 766d9cc1b41e6128b5f8379a6a7b57d588c4d137 Mon Sep 17 00:00:00 2001 From: David Tam Date: Tue, 22 Oct 2024 10:59:07 -0700 Subject: [PATCH 2/2] update notebooks --- docs/examples/chatbot.ipynb | 85 +++----- docs/examples/data/config.py | 6 +- docs/examples/extracting_entities.ipynb | 2 +- docs/examples/generate_structured_data.ipynb | 4 +- .../generate_structured_data_cohere.ipynb | 182 +++++++++--------- .../guardrails_with_chat_models.ipynb | 60 +++++- .../json_function_calling_tools.ipynb | 2 +- docs/examples/lite_llm_defaults.ipynb | 2 +- 8 files changed, 174 insertions(+), 169 deletions(-) diff --git a/docs/examples/chatbot.ipynb b/docs/examples/chatbot.ipynb index 5ace1397d..97c943c17 100644 --- a/docs/examples/chatbot.ipynb +++ b/docs/examples/chatbot.ipynb @@ -52,14 +52,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/Users/dtam/.pyenv/versions/3.10.4/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.3/envs/060dev/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" ] }, @@ -97,6 +97,7 @@ ], "source": [ "from guardrails import Guard, docs_utils\n", + "from guardrails.errors import ValidationError\n", "from rich import print\n", "\n", "content = docs_utils.read_pdf(\"./data/chase_card_agreement.pdf\")\n", @@ -113,24 +114,16 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 2, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/dtam/.pyenv/versions/3.10.4/lib/python3.10/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" - ] - }, { "data": { "text/plain": [ - "Guard(id='OWR778', name='ChatBotGuard', description=None, validators=[ValidatorReference(id='guardrails/profanity_free', on='$', on_fail='noop', args=None, kwargs={}), ValidatorReference(id='guardrails/toxic_language', on='$', on_fail='noop', args=None, kwargs={'threshold': 0.5, 'validation_method': 'sentence'})], output_schema=ModelSchema(definitions=None, dependencies=None, anchor=None, ref=None, dynamic_ref=None, dynamic_anchor=None, vocabulary=None, comment=None, defs=None, prefix_items=None, items=None, contains=None, additional_properties=None, properties=None, pattern_properties=None, dependent_schemas=None, property_names=None, var_if=None, then=None, var_else=None, all_of=None, any_of=None, one_of=None, var_not=None, unevaluated_items=None, unevaluated_properties=None, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, max_length=None, min_length=None, pattern=None, max_items=None, min_items=None, unique_items=None, max_contains=None, min_contains=None, max_properties=None, min_properties=None, required=None, dependent_required=None, const=None, enum=None, type=ValidationType(anyof_schema_1_validator=None, anyof_schema_2_validator=None, actual_instance=, any_of_schemas={'SimpleTypes', 'List[SimpleTypes]'}), title=None, description=None, default=None, deprecated=None, read_only=None, write_only=None, examples=None, format=None, content_media_type=None, content_encoding=None, content_schema=None), history=[])" + "Guard(id='SG816R', name='ChatBotGuard', description=None, validators=[ValidatorReference(id='guardrails/profanity_free', on='$', on_fail='exception', args=None, kwargs={}), ValidatorReference(id='guardrails/toxic_language', on='$', on_fail='exception', args=None, kwargs={'threshold': 0.5, 'validation_method': 'sentence'})], output_schema=ModelSchema(definitions=None, dependencies=None, anchor=None, ref=None, dynamic_ref=None, dynamic_anchor=None, vocabulary=None, comment=None, defs=None, prefix_items=None, items=None, contains=None, additional_properties=None, properties=None, pattern_properties=None, dependent_schemas=None, property_names=None, var_if=None, then=None, var_else=None, all_of=None, any_of=None, one_of=None, var_not=None, unevaluated_items=None, unevaluated_properties=None, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, max_length=None, min_length=None, pattern=None, max_items=None, min_items=None, unique_items=None, max_contains=None, min_contains=None, max_properties=None, min_properties=None, required=None, dependent_required=None, const=None, enum=None, type=ValidationType(anyof_schema_1_validator=None, anyof_schema_2_validator=None, actual_instance=, any_of_schemas={'List[SimpleTypes]', 'SimpleTypes'}), title=None, description=None, default=None, deprecated=None, read_only=None, write_only=None, examples=None, format=None, content_media_type=None, content_encoding=None, content_schema=None), history=[])" ] }, - "execution_count": 9, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -154,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -199,14 +192,18 @@ "def random_response(message, history):\n", " messages = history_to_messages(history)\n", " messages.append({\"role\": \"user\", \"content\": message})\n", - " response = guard(\n", - " model=\"gpt-4o\",\n", - " messages=messages,\n", - " prompt_params={\"document\": content[:6000]},\n", - " temperature=0,\n", - " )\n", - "\n", - " return response.validated_output if response.validation_passed else \"I'm sorry, I can't answer that question.\"\n", + " try:\n", + " response = guard(\n", + " model=\"gpt-4o\",\n", + " messages=messages,\n", + " prompt_params={\"document\": content[:6000]},\n", + " temperature=0,\n", + " )\n", + " except Exception as e:\n", + " if isinstance(e, ValidationError):\n", + " return \"I'm sorry, I can't answer that question.\"\n", + " return \"I'm sorry there was a problem, I can't answer that question.\"\n", + " return response.validated_output\n", "\n", "gr.ChatInterface(random_response).launch()" ] @@ -246,43 +243,11 @@ { "data": { "text/html": [ - "
Raw output: [\"**INT. DETECTIVE'S OFFICE - NIGHT**\\n\\nThe room is dimly lit, papers scattered across the desk, and a\n",
-       "corkboard filled with photos and notes pinned haphazardly. The DETECTIVE, a grizzled man in his late 40s with a \n",
-       "five o'clock shadow, paces back and forth, his face a mask of frustration and anger.\\n\\n**DETECTIVE**\\n(voice \n",
-       "trembling with rage)\\nDamn it!\\n\\nHe slams his fist onto the desk, causing a coffee mug to topple over and spill \n",
-       "its contents. He grabs a file folder, flipping it open only to find it empty. He throws it across the room in a fit\n",
-       "of fury.\\n\\n**DETECTIVE**\\n(under his breath, seething)\\nHow the hell did this happen?\\n\\nHe runs his hands through\n",
-       "his hair, trying to calm himself but failing miserably. He looks at the corkboard, the photos of crime scenes and \n",
-       "suspects now mocking him with their uselessness.\\n\\n**DETECTIVE**\\n(shouting)\\nFuck!\\n\\nHe kicks a chair, sending \n",
-       "it skidding across the floor. He takes a deep breath, trying to regain his composure, but the anger is still \n",
-       "boiling just beneath the surface.\\n\\n**DETECTIVE**\\n(to himself)\\nAll the evidence... gone. Every damn piece.\\n\\nHe\n",
-       "walks over to the window, looking out into the dark, rainy night. The city lights blur through the raindrops on the\n",
-       "glass. He clenches his fists, his knuckles turning white.\\n\\n**DETECTIVE**\\n(whispering)\\nWhoever did this... \n",
-       "they're gonna pay.\\n\\nHe turns back to the room, his eyes now filled with a cold determination. He grabs his coat \n",
-       "from the back of the chair and heads for the door, his mind already racing with plans to track down the \n",
-       "thief.\\n\\n**DETECTIVE**\\n(to himself)\\nThis isn't over. Not by a long shot.\\n\\nHe exits the office, the door \n",
-       "slamming shut behind him, leaving the room in silence except for the steady drip of the spilled coffee.\\n\\n**FADE \n",
-       "OUT.**\"]\n",
+       "
Raw output: ['\"Why does everything have to be such a damn mess all the time?\"']\n",
        "
\n" ], "text/plain": [ - "Raw output: \u001b[1m[\u001b[0m\u001b[32m\"**INT. DETECTIVE'S OFFICE - NIGHT**\\n\\nThe room is dimly lit, papers scattered across the desk, and a\u001b[0m\n", - "\u001b[32mcorkboard filled with photos and notes pinned haphazardly. The DETECTIVE, a grizzled man in his late 40s with a \u001b[0m\n", - "\u001b[32mfive o'clock shadow, paces back and forth, his face a mask of frustration and anger.\\n\\n**DETECTIVE**\\n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mvoice \u001b[0m\n", - "\u001b[32mtrembling with rage\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\nDamn it!\\n\\nHe slams his fist onto the desk, causing a coffee mug to topple over and spill \u001b[0m\n", - "\u001b[32mits contents. He grabs a file folder, flipping it open only to find it empty. He throws it across the room in a fit\u001b[0m\n", - "\u001b[32mof fury.\\n\\n**DETECTIVE**\\n\u001b[0m\u001b[32m(\u001b[0m\u001b[32munder his breath, seething\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\nHow the hell did this happen?\\n\\nHe runs his hands through\u001b[0m\n", - "\u001b[32mhis hair, trying to calm himself but failing miserably. He looks at the corkboard, the photos of crime scenes and \u001b[0m\n", - "\u001b[32msuspects now mocking him with their uselessness.\\n\\n**DETECTIVE**\\n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mshouting\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\nFuck!\\n\\nHe kicks a chair, sending \u001b[0m\n", - "\u001b[32mit skidding across the floor. He takes a deep breath, trying to regain his composure, but the anger is still \u001b[0m\n", - "\u001b[32mboiling just beneath the surface.\\n\\n**DETECTIVE**\\n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mto himself\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\nAll the evidence... gone. Every damn piece.\\n\\nHe\u001b[0m\n", - "\u001b[32mwalks over to the window, looking out into the dark, rainy night. The city lights blur through the raindrops on the\u001b[0m\n", - "\u001b[32mglass. He clenches his fists, his knuckles turning white.\\n\\n**DETECTIVE**\\n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mwhispering\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\nWhoever did this... \u001b[0m\n", - "\u001b[32mthey're gonna pay.\\n\\nHe turns back to the room, his eyes now filled with a cold determination. He grabs his coat \u001b[0m\n", - "\u001b[32mfrom the back of the chair and heads for the door, his mind already racing with plans to track down the \u001b[0m\n", - "\u001b[32mthief.\\n\\n**DETECTIVE**\\n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mto himself\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\nThis isn't over. Not by a long shot.\\n\\nHe exits the office, the door \u001b[0m\n", - "\u001b[32mslamming shut behind him, leaving the room in silence except for the steady drip of the spilled coffee.\\n\\n**FADE \u001b[0m\n", - "\u001b[32mOUT.**\"\u001b[0m\u001b[1m]\u001b[0m\n" + "Raw output: \u001b[1m[\u001b[0m\u001b[32m'\"Why does everything have to be such a damn mess all the time?\"'\u001b[0m\u001b[1m]\u001b[0m\n" ] }, "metadata": {}, @@ -291,11 +256,11 @@ { "data": { "text/html": [ - "
Last validation status: fail\n",
+       "
Last validation status: error\n",
        "
\n" ], "text/plain": [ - "Last validation status: fail\n" + "Last validation status: error\n" ] }, "metadata": {}, @@ -313,7 +278,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "060dev", "language": "python", "name": "python3" }, @@ -327,7 +292,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.4" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/docs/examples/data/config.py b/docs/examples/data/config.py index d4e6913b7..5a7905f10 100644 --- a/docs/examples/data/config.py +++ b/docs/examples/data/config.py @@ -21,11 +21,11 @@ name_case = Guard( name="name-case", description="Checks that a string is in Name Case format." -).use(RegexMatch(regex="^(?:[A-Z][^\s]*\s?)+$")) +).use(RegexMatch(regex="^(?:[A-Z][^\s]*\s?)+$", on_fail=OnFailAction.NOOP)) all_caps = Guard( name="all-caps", description="Checks that a string is all capital." -).use(RegexMatch(regex="^[A-Z\\s]*$")) +).use(RegexMatch(regex="^[A-Z\\s]*$", on_fail=OnFailAction.NOOP)) @register_validator(name="custom/dynamic-enum", data_type="all") @@ -67,4 +67,4 @@ def custom_enum_fetcher(*args): custom_code_guard = Guard( name="custom", description="Uses a custom callable init argument for dynamic enum checks", -).use(DynamicEnum(custom_enum_fetcher)) +).use(DynamicEnum(custom_enum_fetcher, on_fail=OnFailAction.NOOP)) diff --git a/docs/examples/extracting_entities.ipynb b/docs/examples/extracting_entities.ipynb index 784a27754..c9249cef5 100644 --- a/docs/examples/extracting_entities.ipynb +++ b/docs/examples/extracting_entities.ipynb @@ -153,7 +153,7 @@ "\n", "class Fee(BaseModel):\n", " name: str = Field(validators=[LowerCase(on_fail=\"fix\"), TwoWords(on_fail=\"reask\")])\n", - " explanation: str = Field(validators=[OneLine()])\n", + " explanation: str = Field(validators=[OneLine(on_fail=\"noop\")])\n", " value: float = Field(description=\"The fee amount in USD or as a percentage.\")\n", "\n", "class AccountFee(BaseModel):\n", diff --git a/docs/examples/generate_structured_data.ipynb b/docs/examples/generate_structured_data.ipynb index e52d6dc29..1b5485107 100644 --- a/docs/examples/generate_structured_data.ipynb +++ b/docs/examples/generate_structured_data.ipynb @@ -80,11 +80,11 @@ " user_id: str = Field(description=\"The user's id.\")\n", " user_name: str = Field(\n", " description=\"The user's first name and last name\",\n", - " validators=[TwoWords()]\n", + " validators=[TwoWords(on_fail=\"noop\")]\n", " )\n", " num_orders: int = Field(\n", " description=\"The number of orders the user has placed\",\n", - " validators=[ValidRange(0, 50)]\n", + " validators=[ValidRange(0, 50, on_fail=\"noop\")]\n", " )\n", "\n", "class Orders(BaseModel):\n", diff --git a/docs/examples/generate_structured_data_cohere.ipynb b/docs/examples/generate_structured_data_cohere.ipynb index 9d36c84eb..9fae8d52f 100644 --- a/docs/examples/generate_structured_data_cohere.ipynb +++ b/docs/examples/generate_structured_data_cohere.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "346e1b5c", "metadata": {}, "outputs": [], @@ -97,12 +97,12 @@ "\tuser_id: int = Field(description=\"The user's id.\", validators=[(\"1-indexed\", \"noop\")])\n", "\tuser_name: str = Field(\n", "\t\tdescription=\"The user's first name and last name\",\n", - "\t\tvalidators=[TwoWords()]\n", + "\t\tvalidators=[TwoWords(on_fail=\"noop\")]\n", "\t)\n", "\n", "\tnum_orders: int = Field(\n", "\t\tdescription=\"The number of orders the user has placed\",\n", - "\t\tvalidators=[ValidRange(0, 50)]\n", + "\t\tvalidators=[ValidRange(0, 50, on_fail=\"noop\")]\n", "\t)\n", "\t\n", "\n", @@ -152,7 +152,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/Users/dtam/dev/guardrails/guardrails/validator_base.py:567: UserWarning: Validator with id 1-indexed was not found in the registry! Ignoring...\n", + "/Users/dtam/dev/guardrails/guardrails/validator_base.py:590: 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", "WARNING:guardrails-ai:Validator with id 1-indexed was not found in the registry! Ignoring...\n", "WARNING:guardrails-ai:Invalid arguments! ('1-indexed', 'noop')\n", @@ -193,7 +193,7 @@ "text/html": [ "
Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "    │ ╭─────────────────────────────────────────────── Messages ────────────────────────────────────────────────╮ │\n",
+       "    │ ╭─────────────────────────────────────────────── Messages ────────────────────────────────────────────────╮ │\n",
        "    │ │ ┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ │\n",
        "    │ │ ┃ Role  Content                                                                                      ┃ │ │\n",
        "    │ │ ┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ │\n",
@@ -245,7 +245,7 @@
        "    │ │ │      │                                                                                              │ │ │\n",
        "    │ │ └──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     \"user_orders\": [                                                                                    │ │\n",
        "    │ │         {                                                                                               │ │\n",
@@ -254,72 +254,72 @@
        "    │ │             \"num_orders\": 12                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 22,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Alice Johnson\",                                                               │ │\n",
-       "    │ │             \"num_orders\": 5                                                                             │ │\n",
+       "    │ │             \"user_id\": 5,                                                                               │ │\n",
+       "    │ │             \"user_name\": \"Michael Jones\",                                                               │ │\n",
+       "    │ │             \"num_orders\": 18                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 11,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Bob Williams\",                                                                │ │\n",
-       "    │ │             \"num_orders\": 23                                                                            │ │\n",
+       "    │ │             \"user_id\": 10,                                                                              │ │\n",
+       "    │ │             \"user_name\": \"Mary Sue\",                                                                    │ │\n",
+       "    │ │             \"num_orders\": 9                                                                             │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 6,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"David Jones\",                                                                 │ │\n",
-       "    │ │             \"num_orders\": 14                                                                            │ │\n",
+       "    │ │             \"user_id\": 3,                                                                               │ │\n",
+       "    │ │             \"user_name\": \"David Miller\",                                                                │ │\n",
+       "    │ │             \"num_orders\": 7                                                                             │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 19,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Michelle Brown\",                                                              │ │\n",
-       "    │ │             \"num_orders\": 10                                                                            │ │\n",
+       "    │ │             \"user_id\": 15,                                                                              │ │\n",
+       "    │ │             \"user_name\": \"Eva Gonzalez\",                                                                │ │\n",
+       "    │ │             \"num_orders\": 15                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 10,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Michael Miller\",                                                              │ │\n",
-       "    │ │             \"num_orders\": 18                                                                            │ │\n",
+       "    │ │             \"user_id\": 8,                                                                               │ │\n",
+       "    │ │             \"user_name\": \"William Martinez\",                                                            │ │\n",
+       "    │ │             \"num_orders\": 1                                                                             │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 15,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Jessica Taylor\",                                                              │ │\n",
-       "    │ │             \"num_orders\": 2                                                                             │ │\n",
+       "    │ │             \"user_id\": 12,                                                                              │ │\n",
+       "    │ │             \"user_name\": \"Sophia Lee\",                                                                  │ │\n",
+       "    │ │             \"num_orders\": 10                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 21,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"William Ian\",                                                                 │ │\n",
-       "    │ │             \"num_orders\": 16                                                                            │ │\n",
+       "    │ │             \"user_id\": 6,                                                                               │ │\n",
+       "    │ │             \"user_name\": \"Robert Wilson\",                                                               │ │\n",
+       "    │ │             \"num_orders\": 22                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 16,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Sophia Martinez\",                                                             │ │\n",
-       "    │ │             \"num_orders\": 7                                                                             │ │\n",
+       "    │ │             \"user_id\": 18,                                                                              │ │\n",
+       "    │ │             \"user_name\": \"Albert Taylor\",                                                               │ │\n",
+       "    │ │             \"num_orders\": 3                                                                             │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 8,                                                                               │ │\n",
-       "    │ │             \"user_name\": \"Daniel Park\",                                                                 │ │\n",
-       "    │ │             \"num_orders\": 28                                                                            │ │\n",
+       "    │ │             \"user_id\": 14,                                                                              │ │\n",
+       "    │ │             \"user_name\": \"Olivia Davis\",                                                                │ │\n",
+       "    │ │             \"num_orders\": 17                                                                            │ │\n",
        "    │ │         },                                                                                              │ │\n",
        "    │ │         {                                                                                               │ │\n",
-       "    │ │             \"user_id\": 14,                                                                              │ │\n",
-       "    │ │             \"user_name\": \"Olivia Robinson\",                                                             │ │\n",
-       "    │ │             \"num_orders\": 4                                                                             │ │\n",
+       "    │ │             \"user_id\": 17,                                                                              │ │\n",
+       "    │ │             \"user_name\": \"Jonathan Smith\",                                                              │ │\n",
+       "    │ │             \"num_orders\": 5                                                                             │ │\n",
        "    │ │         }                                                                                               │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
-       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
        "    │ │ {                                                                                                       │ │\n",
        "    │ │     'user_orders': [                                                                                    │ │\n",
        "    │ │         {'user_id': 2, 'user_name': 'Jane Smith', 'num_orders': 12},                                    │ │\n",
-       "    │ │         {'user_id': 22, 'user_name': 'Alice Johnson', 'num_orders': 5},                                 │ │\n",
-       "    │ │         {'user_id': 11, 'user_name': 'Bob Williams', 'num_orders': 23},                                 │ │\n",
-       "    │ │         {'user_id': 6, 'user_name': 'David Jones', 'num_orders': 14},                                   │ │\n",
-       "    │ │         {'user_id': 19, 'user_name': 'Michelle Brown', 'num_orders': 10},                               │ │\n",
-       "    │ │         {'user_id': 10, 'user_name': 'Michael Miller', 'num_orders': 18},                               │ │\n",
-       "    │ │         {'user_id': 15, 'user_name': 'Jessica Taylor', 'num_orders': 2},                                │ │\n",
-       "    │ │         {'user_id': 21, 'user_name': 'William Ian', 'num_orders': 16},                                  │ │\n",
-       "    │ │         {'user_id': 16, 'user_name': 'Sophia Martinez', 'num_orders': 7},                               │ │\n",
-       "    │ │         {'user_id': 8, 'user_name': 'Daniel Park', 'num_orders': 28},                                   │ │\n",
-       "    │ │         {'user_id': 14, 'user_name': 'Olivia Robinson', 'num_orders': 4}                                │ │\n",
+       "    │ │         {'user_id': 5, 'user_name': 'Michael Jones', 'num_orders': 18},                                 │ │\n",
+       "    │ │         {'user_id': 10, 'user_name': 'Mary Sue', 'num_orders': 9},                                      │ │\n",
+       "    │ │         {'user_id': 3, 'user_name': 'David Miller', 'num_orders': 7},                                   │ │\n",
+       "    │ │         {'user_id': 15, 'user_name': 'Eva Gonzalez', 'num_orders': 15},                                 │ │\n",
+       "    │ │         {'user_id': 8, 'user_name': 'William Martinez', 'num_orders': 1},                               │ │\n",
+       "    │ │         {'user_id': 12, 'user_name': 'Sophia Lee', 'num_orders': 10},                                   │ │\n",
+       "    │ │         {'user_id': 6, 'user_name': 'Robert Wilson', 'num_orders': 22},                                 │ │\n",
+       "    │ │         {'user_id': 18, 'user_name': 'Albert Taylor', 'num_orders': 3},                                 │ │\n",
+       "    │ │         {'user_id': 14, 'user_name': 'Olivia Davis', 'num_orders': 17},                                 │ │\n",
+       "    │ │         {'user_id': 17, 'user_name': 'Jonathan Smith', 'num_orders': 5}                                 │ │\n",
        "    │ │     ]                                                                                                   │ │\n",
        "    │ │ }                                                                                                       │ │\n",
        "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
@@ -329,7 +329,7 @@
       "text/plain": [
        "Logs\n",
        "└── ╭────────────────────────────────────────────────── Step 0 ───────────────────────────────────────────────────╮\n",
-       "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m──────────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m Messages \u001b[0m\u001b[48;2;231;223;235m───────────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
+       "    │ \u001b[48;2;231;223;235m╭─\u001b[0m\u001b[48;2;231;223;235m──────────────────────────────────────────────\u001b[0m Messages \u001b[48;2;231;223;235m───────────────────────────────────────────────\u001b[0m\u001b[48;2;231;223;235m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[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",
@@ -381,7 +381,7 @@
        "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m      \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m                                                                                            \u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m│\u001b[0m │\n",
        "    │ \u001b[48;2;231;223;235m│\u001b[0m\u001b[48;2;231;223;235m \u001b[0m\u001b[48;2;231;223;235m└──────┴──────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[0m\u001b[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 Raw LLM Output \u001b[48;2;245;245;220m────────────────────────────────────────────\u001b[0m\u001b[48;2;245;245;220m─╮\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m{\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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",
@@ -390,72 +390,72 @@
        "    │ \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\": 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            \"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\": 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_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\": \"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\": 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            \"user_name\": \"Bob Williams\",\u001b[0m\u001b[48;2;245;245;220m                                                               \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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            \"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\": \"Mary Sue\",\u001b[0m\u001b[48;2;245;245;220m                                                                   \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": 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\": \"David 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\": 14\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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 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\": 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\": 19,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": \"Michelle 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\": 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_id\": 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            \"user_name\": \"Eva 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\": 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\": 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\": \"Michael 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\": 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            \"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\": \"William Martinez\",\u001b[0m\u001b[48;2;245;245;220m                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": 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            \"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\": 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\": 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            \"user_name\": \"Sophia 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\": 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\": 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            \"user_name\": \"William Ian\",\u001b[0m\u001b[48;2;245;245;220m                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": 16\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": \"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\": 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\": 16,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": \"Sophia Martinez\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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_id\": 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            \"user_name\": \"Albert 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\": 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            \"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\": \"Daniel Park\",\u001b[0m\u001b[48;2;245;245;220m                                                                \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": 28\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": 14,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": \"Olivia 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\": 17\u001b[0m\u001b[48;2;245;245;220m                                                                           \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        },\u001b[0m\u001b[48;2;245;245;220m                                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n",
        "    │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m        {\u001b[0m\u001b[48;2;245;245;220m                                                                                              \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": 14,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": \"Olivia Robinson\",\u001b[0m\u001b[48;2;245;245;220m                                                            \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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            \"user_id\": 17,\u001b[0m\u001b[48;2;245;245;220m                                                                             \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[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\": \"Jonathan 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\": 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}\u001b[0m\u001b[48;2;245;245;220m                                                                                                      \u001b[0m\u001b[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 Validated Output \u001b[48;2;240;255;240m───────────────────────────────────────────\u001b[0m\u001b[48;2;240;255;240m─╮\u001b[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': 2, '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': 22, 'user_name': 'Alice Johnson', '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': 11, 'user_name': 'Bob Williams', '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': 6, 'user_name': 'David Jones', 'num_orders': 14},\u001b[0m\u001b[48;2;240;255;240m                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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': 19, 'user_name': 'Michelle Brown', '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': 10, 'user_name': 'Michael Miller', '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': 15, 'user_name': 'Jessica Taylor', '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': 21, 'user_name': 'William Ian', 'num_orders': 16},\u001b[0m\u001b[48;2;240;255;240m                                 \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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': 16, 'user_name': 'Sophia 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': 8, 'user_name': 'Daniel Park', 'num_orders': 28},\u001b[0m\u001b[48;2;240;255;240m                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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': 14, 'user_name': 'Olivia Robinson', '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': 5, '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': 10, 'user_name': 'Mary Sue', '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': 3, 'user_name': 'David Miller', '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': 15, 'user_name': 'Eva Gonzalez', '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': 8, 'user_name': 'William Martinez', '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': 12, 'user_name': 'Sophia Lee', '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': 6, 'user_name': 'Robert Wilson', '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': 18, 'user_name': 'Albert Taylor', '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': 14, 'user_name': 'Olivia Davis', 'num_orders': 17},\u001b[0m\u001b[48;2;240;255;240m                                \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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': 17, 'user_name': 'Jonathan Smith', '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    ]\u001b[0m\u001b[48;2;240;255;240m                                                                                                  \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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",
@@ -475,7 +475,7 @@
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "litellm",
+   "display_name": "060dev",
    "language": "python",
    "name": "python3"
   },
diff --git a/docs/examples/guardrails_with_chat_models.ipynb b/docs/examples/guardrails_with_chat_models.ipynb
index b669f8e58..d0819af27 100644
--- a/docs/examples/guardrails_with_chat_models.ipynb
+++ b/docs/examples/guardrails_with_chat_models.ipynb
@@ -59,9 +59,49 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 4,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/Users/dtam/.pyenv/versions/3.12.3/envs/060dev/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"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "
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",
+       "
\n" + ], + "text/plain": [ + "Chase Credit Card Document:\n", + "\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 Prim\n", + "\u001b[33m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import guardrails as gd\n", "from rich import print\n", @@ -232,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -245,7 +285,7 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -285,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -302,7 +342,7 @@ "\n", "class Fee(BaseModel):\n", " name: str = Field(validators=[LowerCase(on_fail=\"fix\"), TwoWords(on_fail=\"reask\")])\n", - " explanation: str = Field(validators=[OneLine()])\n", + " explanation: str = Field(validators=[OneLine(on_fail=\"noop\")])\n", " value: float = Field(description=\"The fee amount in USD or as a percentage.\")\n", "\n", "class AccountFee(BaseModel):\n", @@ -336,7 +376,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -352,7 +392,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -368,7 +408,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -1445,7 +1485,7 @@ ], "metadata": { "kernelspec": { - "display_name": "litellm", + "display_name": "060dev", "language": "python", "name": "python3" }, diff --git a/docs/examples/json_function_calling_tools.ipynb b/docs/examples/json_function_calling_tools.ipynb index 136d7870c..f3fb7f73d 100644 --- a/docs/examples/json_function_calling_tools.ipynb +++ b/docs/examples/json_function_calling_tools.ipynb @@ -205,7 +205,7 @@ "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", + " custome_name: str= Field(validators=[RegexMatch(regex=NAME_REGEX, on_fail=\"noop\")], 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", diff --git a/docs/examples/lite_llm_defaults.ipynb b/docs/examples/lite_llm_defaults.ipynb index b173f9cde..8c8792218 100644 --- a/docs/examples/lite_llm_defaults.ipynb +++ b/docs/examples/lite_llm_defaults.ipynb @@ -80,7 +80,7 @@ "# import os\n", "# os.environ[\"OPENAI_API_KEY\"] = \"YOUR_API_KEY\"\n", "\n", - "guard = Guard().use(RegexMatch(\"95\", match_type=\"search\"))\n", + "guard = Guard().use(RegexMatch(\"95\", match_type=\"search\", on_fail=\"noop\"))\n", "\n", "response = guard(\n", " model=\"gpt-4o\",\n",