From 1b4dff647b76ef2f38ef8813f9eda0193b3af8f7 Mon Sep 17 00:00:00 2001 From: Caleb Courier Date: Tue, 25 Jun 2024 15:27:49 -0500 Subject: [PATCH 1/5] first draft --- docs/migration_guides/0-5-migration.md | 281 +++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 docs/migration_guides/0-5-migration.md diff --git a/docs/migration_guides/0-5-migration.md b/docs/migration_guides/0-5-migration.md new file mode 100644 index 000000000..9ade57bb1 --- /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.add_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.add_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 key-word 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 From dbc3e1ddae84e2ee70bf4e85cca16711c4c0e1e3 Mon Sep 17 00:00:00 2001 From: Caleb Courier Date: Tue, 25 Jun 2024 16:45:38 -0500 Subject: [PATCH 2/5] start doc updates; add demo notebooks for 0.5.0 --- .github/workflows/scripts/run_notebooks.sh | 2 +- docs/api_reference/actions.md | 4 + docs/api_reference/async_guard.md | 22 + docs/api_reference/constants.md | 4 + docs/api_reference/errors.md | 7 + docs/api_reference/guard.md | 8 +- docs/api_reference/types.md | 1 + docs/api_reference/validators.md | 17 +- docs/examples/constrained_decoding.ipynb | 93 ++ docs/examples/data/config.py | 70 ++ docs/examples/guard_use.ipynb | 125 +++ docs/examples/guardrails_server.ipynb | 414 ++++++++ .../json_function_calling_tools.ipynb | 989 ++++++++++++++++++ docs/examples/lite_llm_defaults.ipynb | 91 ++ guardrails/actions/filter.py | 1 + guardrails/actions/refrain.py | 4 + .../classes/validation/validation_result.py | 16 +- guardrails/errors/__init__.py | 17 +- guardrails/guard.py | 25 +- 19 files changed, 1866 insertions(+), 44 deletions(-) create mode 100644 docs/api_reference/actions.md create mode 100644 docs/api_reference/async_guard.md create mode 100644 docs/api_reference/constants.md create mode 100644 docs/api_reference/errors.md create mode 100644 docs/api_reference/types.md create mode 100644 docs/examples/constrained_decoding.ipynb create mode 100644 docs/examples/data/config.py create mode 100644 docs/examples/guard_use.ipynb create mode 100644 docs/examples/guardrails_server.ipynb create mode 100644 docs/examples/json_function_calling_tools.ipynb create mode 100644 docs/examples/lite_llm_defaults.ipynb diff --git a/.github/workflows/scripts/run_notebooks.sh b/.github/workflows/scripts/run_notebooks.sh index cd854ceb6..66075f5e8 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") if [[ ! " ${invalid_notebooks[@]} " =~ " ${notebook} " ]]; then echo "Processing $notebook..." # poetry run jupyter nbconvert --to notebook --execute "$notebook" diff --git a/docs/api_reference/actions.md b/docs/api_reference/actions.md new file mode 100644 index 000000000..c56c3b0a4 --- /dev/null +++ b/docs/api_reference/actions.md @@ -0,0 +1,4 @@ + + + +::: guardrails.actions \ No newline at end of file diff --git a/docs/api_reference/async_guard.md b/docs/api_reference/async_guard.md new file mode 100644 index 000000000..9c27104a5 --- /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" + - "add_json_function_calling_tool" + - "to_dict" + - "from_dict" + - "to_runnable" diff --git a/docs/api_reference/constants.md b/docs/api_reference/constants.md new file mode 100644 index 000000000..7c8ffee4b --- /dev/null +++ b/docs/api_reference/constants.md @@ -0,0 +1,4 @@ + + + +::: guardrails.constants \ No newline at end of file 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 1c4950e64..6f8873d91 100644 --- a/docs/api_reference/guard.md +++ b/docs/api_reference/guard.md @@ -9,12 +9,14 @@ - "from_rail_string" - "from_pydantic" - "from_string" + - "configure" - "use" - "use_many" - - "to_runnable" - - "configure" - "__call__" - "parse" - "validate" - - "history" - "error_spans_in_output" + - "add_json_function_calling_tool" + - "to_dict" + - "from_dict" + - "to_runnable" 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 index 447417a4d..a6a7263e1 100644 --- a/docs/api_reference/validators.md +++ b/docs/api_reference/validators.md @@ -1,18 +1,3 @@ -::: guardrails.validators - options: - filters: - - "!logger" - - "!types_to_validators" - - "!validators_registry" - - "!EventDetail" - - "!Validator" - - "!validate" - - "!register_validator" - - "!PydanticReAsk" - - "!Refrain" - - "!ValidationResult" - - "!PassResult" - - "!FailResult" - - "!__*" +::: guardrails.validators \ No newline at end of file diff --git a/docs/examples/constrained_decoding.ipynb b/docs/examples/constrained_decoding.ipynb new file mode 100644 index 000000000..03cdf447a --- /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/guard_use.ipynb b/docs/examples/guard_use.ipynb new file mode 100644 index 000000000..9f4b5230c --- /dev/null +++ b/docs/examples/guard_use.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "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": 5, + "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": 6, + "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": 10, + "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.3" + } + }, + "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..f9d933457 --- /dev/null +++ b/docs/examples/guardrails_server.ipynb @@ -0,0 +1,414 @@ +{ + "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.0a4\" -q" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/Users/calebcourier/Downloads/demo-050/.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": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Run this in a terminal\n", + "# guardrails start --config=./data/config.py" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
some-token\n",
+       "
\n" + ], + "text/plain": [ + "some-token\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
http://localhost:8000\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[4;94mhttp://localhost:8000\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import os\n", + "\n", + "os.environ[\"GUARDRAILS_API_KEY\"] = \"some-token\"\n", + "os.environ[\"GUARDRAILS_BASE_URL\"] = \"http://localhost:8000\"\n", + "\n", + "\n", + "print(os.environ.get(\"GUARDRAILS_API_KEY\"))\n", + "print(os.environ.get(\"GUARDRAILS_BASE_URL\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/calebcourier/Downloads/demo-050/.venv/lib/python3.12/site-packages/guardrails/validator_base.py:144: UserWarning: Validator with id guardrails/regex_match was not found in the registry! Ignoring...\n", + " warn(f\"Validator with id {name} was not found in the registry! Ignoring...\")\n" + ] + }, + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='4593646352',\n",
+       "    raw_llm_output='z-dawg',\n",
+       "    validated_output='z-dawg',\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'4593646352'\u001b[0m,\n", + " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n", + " \u001b[33mvalidated_output\u001b[0m=\u001b[32m'z-dawg'\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": [ + "import logging\n", + "from rich import print\n", + "from guardrails import configure_logging\n", + "from guardrails import Guard\n", + "\n", + "\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=\"z-dawg\"\n", + ")\n", + "\n", + "print(response)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
[\n",
+       "    Call(\n",
+       "        id='4593646352',\n",
+       "        iterations=[\n",
+       "            Iteration(\n",
+       "                id='4588121904',\n",
+       "                index=0,\n",
+       "                call_id='4593646352',\n",
+       "                inputs=Inputs(\n",
+       "                    llm_api=None,\n",
+       "                    llm_output='z-dawg',\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='z-dawg',\n",
+       "                        stream_output=None,\n",
+       "                        async_stream_output=None\n",
+       "                    ),\n",
+       "                    raw_output=None,\n",
+       "                    parsed_output='z-dawg',\n",
+       "                    validation_response='z-dawg',\n",
+       "                    guarded_output='z-dawg',\n",
+       "                    reasks=[],\n",
+       "                    validator_logs=[\n",
+       "                        ValidatorLogs(\n",
+       "                            validator_name='RegexMatch',\n",
+       "                            registered_name='guardrails/regex_match',\n",
+       "                            instance_id=4586558176,\n",
+       "                            property_path='$',\n",
+       "                            value_before_validation='z-dawg',\n",
+       "                            value_after_validation='z-dawg',\n",
+       "                            validation_result=FailResult(\n",
+       "                                outcome='fail',\n",
+       "                                error_message='Result must match ^(?:[A-Z][^\\\\s]*\\\\s?)+$',\n",
+       "                                fix_value='Rb[@1K(ZD}uodO$mh]XmheJWHC2lbc\\rA*L(^Hi6el(h1Gdw;f*4\"$b3e+K;_EDp:Rvh,/!T\n",
+       "C}!u4o\"}-B\\\\6Eh6{9qFpw,t[`:y;gOTt22VvnR;[kX_02kE-#R8iJ.8zJbt>\\\\.FW/>\\'QBTtqyym]Ra4\\'>;\\'imC_zF14Ks`BE@k_NA \n",
+       "Bq*_Q9~Q>hv33+ktfKk|;+k|?GMcF~>z6]j&$7Cb{A},#P.Lw]Al1lU\\':Ig3Q*Ezm8I4\\'|RoR9K-vRf+yN]8`PYO0G=7BWxLDr2kQ4`4lZ!,jW;YY\n",
+       "38eUep*UOV~0@z#$N*3PldH0solD7Q^lu\\\\$RSJ[O*3)B$C{8oK_]U6#Kd}1)pZ?Doqm8J#`QDK*H2:I8ex]g1[,DT\"#:ZpEW_)Jk>C\\'mA{0IJ{B6+\n",
+       "Z>yIDB#HC@%KMMJ?b=`r6X)M\"`eyvUs`&XL{xRW;\\'s4S<Alf9or39ZM~#:YB5HNNw9CxIhA}6``j7=GS7LE1zH8;|7y*^Gal/>8B\\\\l$c|\\\\9~B@&j\n",
+       "a(\\\\yKa#qL)@/#y}O43&iMBC{0E&ta{`R7`>^&*}bA18$tNQGiVPWl[(Blp{3JA$Dv=pPMMGP,<CQ*Z}!HhvLRDzOL@#}Q{Ppj}!/oLD)DZSP!.GcYc\n",
+       ",hT1:Y9$qrr^L7kT9#>rF~O\\x0cRMfxAYpC!L?-~>T`sM?\\'*LB\\x0cHhODokB5Z@Z21kfc4w&}t3}8F|A.3{\\rNgwdgEI7*cY\"ii-Dk8u4ZaG(C/pD\n",
+       "}X!|Cp&hu*/S5}\\\\l@U&:=?1_(HX(um_.x9X+J.i81snKUZnMt_Lb4hsg|@_$wp+D3a,~?0vw\\'JW4O#xrllcY}WlRA?lzEhsoR3kE,d\\'\"X~N`4;hT\n",
+       "0*\\x0bGaXM{8=N+d)[#65\"d]+.9Bg;X_JU[G/1JHA@@|#*Z)3J38f)DmcE:+/\\x0cHL`Eq*5c#G}f`EXDMPd-Mh5%5_:J)j+;n(ql`eTyoz-CR^c<Re\n",
+       "I!l0,EclkG9&jxkUQM\\x0cITy\\\\{:%WKAo-[Z3MAA?TVAPMeS#D2W@W?*olx,IuKyo3zpPc?aQ;-zu]S6AlIiV0jf)G[M2sl)9?yv<I@.j[42B9vaec\n",
+       "^ubuj]M?\\rGhh;ep2bg\\\\|#DUYh)2#I7$x^]:[K>A-FlCii\"fp~5u`?D$Z(a@r9iY<Baiv$`[rm0vk\\\\fejLZd{V&8`Y-\"VJ16E~*b-&W5mq1mXafz6\n",
+       "4vvjYQ#6%R_x?5Jok*~-D\\\\JK9ccn\\'dB\"^;(|[C:UvhG{R?]b<gCTPYlVu2\\\\?B&mTY=.0ER(TaBY{t:]W#L0l~kXJm\"e=>eg=H!_z`8{Wcb7Xg+9t\n",
+       "v@</J\\\\R6\\\\B@N%gr3^~x%9Ee%&\\\\JU<wEsUm`E2\"=Hi1?kLnsmgU^N^=5w415S@=4_;]Cmul\\rVs`^fZo$<mDX^I}N,NK;}^gvMe\\'_joN\\'3g@:^R\n",
+       "kkJY^LU*3~=FjS;6.UCC|\"UQ\\rUolzK;pWH~6>8qv7?M7,.>e}KfvqmKK9\\'ZdhB;*3)<0,R+Jlt3.go3=UK\\'yj\\'Z==[dOwSe]s(shfX({4~4efq~\n",
+       "5j+;_R(t,H-q,-\\x0bN_/*MiPKOlE)ab0wg\\rAYAJ<VC*Ya8Dt02VaI\\\\X0<:4PGmsVVDj5%aHQN:\\\\k>c7JY^l3{+9AA]~J-(i6[>/am{T)*=:9TZ)\n",
+       "hMyg(W4B61Y5\\\\\\\\R_lRT&$C|19TY#{F!8^\\\\N%b)\\'J?EQoH6<yF7HEcRmfSNz!9*k0!$ARAX^<zb8?uvt,2[DyT|w:vx}MF\\'%mKi\\'&Mg^oJKBu}\n",
+       "(v#6vh\\x0cLF<BZ;2:\\rGIzjF=@qr~Y#ls5\"d,$/C6vhIx77+UZ-}B4w.<xMDZiW;\"1f1R~5fI:DzUEJ.INO4u;f$pol{}I\\nQ=X\\\\\"e~w.e9+8xN\"\\\n",
+       "'Tc0Nor:9mfG<2]KrtG5Z$b?>@)@^zeO\">[A@F6/DA/1:)}]z#K7%|GN/|s;0~rPemA({6S\"y({_Hs@9ON>r0cm\\x0cHeL\\'\\'l~>W?DW\".kEdz=Yn1\n",
+       "E5m=IelWe2k-SP\"|=;(|[=WG2qI\\nYdihR~Dr45%Y@K=[k%g%2$c^xPUbxW*lzVHW@G_ymLo1i\\x0cLAKPz@Y;cc\"iSBiCHM0S)/:>M{%?zeP5_8*N_\n",
+       "ijWjS2Pw=$9\";xE2D;>4-*%XP!3\\'Ggc(ERo\\'b*Jt}:uvSDL(/ \n",
+       "O5s+oyIEoBA%WYA^DAc30aj9fsc\\\\gh\\\\B[xKOrT&%|pg\\x0bOW?wUJOngrPag,&7t4%\\'#}?1JA+z]FIu\\'(JDC{kW4)GSsq[yzZ?6\\'=)5Z]E=4=_\n",
+       "W0eIeebu=8\"~uh<kfQab7%a&y$rRb:WLHx48U}dwCp%]MAvGV]>Q\\\\LA%Hh~*T4~\"t!EZ#pNn?:J#s4VVI)fE \n",
+       "A660O)GO$B6*,J\"9+Dd-Yx\\\\P2cTIVe,t%qvs*@h]wMSYG19,Ww6E4aR44Sat1PF${OG@%,.33A-p9G[Q#sRWZf?7Z0!_v]v$+qzkp^rD=.:E#yUg)]\n",
+       "yXw+/bJp@9<kM?+zYV]:1qa|2zeDL*I^zFa\"=KAZzv?.LssH_(,4\\'[8g1O8tL&1ys|>l\\'z]GG%hPk!J!]$*Ez*kR]%n;H\\\\\\'c&~q<lDN73*|gW2X\n",
+       "B:@joK]}j-_GDuE73e8%G=@A,pj&wTMk!I69S3,>,#?^p;:.ADr)$vv\"Ddb9wV_p--,(7/E$()O`jZ\\rWah00;;/9|bou3$*4Uo/y)Tc8]]SK@,$L\\'\n",
+       "OdL!$Q?!~=j\\'kB\\'L42@nj]$V:9XY^[uQwh*F=%z&L,&:@1I',\n",
+       "                                error_spans=None,\n",
+       "                                metadata=None,\n",
+       "                                validated_chunk=None\n",
+       "                            ),\n",
+       "                            start_time=datetime.datetime(2024, 6, 25, 14, 19, 56, 81461),\n",
+       "                            end_time=datetime.datetime(2024, 6, 25, 14, 19, 56, 94752)\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'4593646352'\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'4588121904'\u001b[0m,\n", + " \u001b[33mindex\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + " \u001b[33mcall_id\u001b[0m=\u001b[32m'4593646352'\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'z-dawg'\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'z-dawg'\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'z-dawg'\u001b[0m,\n", + " \u001b[33mvalidation_response\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n", + " \u001b[33mguarded_output\u001b[0m=\u001b[32m'z-dawg'\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;36m4586558176\u001b[0m,\n", + " \u001b[33mproperty_path\u001b[0m=\u001b[32m'$'\u001b[0m,\n", + " \u001b[33mvalue_before_validation\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n", + " \u001b[33mvalue_after_validation\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n", + " \u001b[33mvalidation_result\u001b[0m=\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'Result must match ^\u001b[0m\u001b[32m(\u001b[0m\u001b[32m?:\u001b[0m\u001b[32m[\u001b[0m\u001b[32mA-Z\u001b[0m\u001b[32m]\u001b[0m\u001b[32m[\u001b[0m\u001b[32m^\\\\s\u001b[0m\u001b[32m]\u001b[0m\u001b[32m*\\\\s?\u001b[0m\u001b[32m)\u001b[0m\u001b[32m+$'\u001b[0m,\n", + " \u001b[33mfix_value\u001b[0m=\u001b[32m'Rb\u001b[0m\u001b[32m[\u001b[0m\u001b[32m@1K\u001b[0m\u001b[32m(\u001b[0m\u001b[32mZD\u001b[0m\u001b[32m}\u001b[0m\u001b[32muodO$mh\u001b[0m\u001b[32m]\u001b[0m\u001b[32mXmheJWHC2lbc\\rA*L\u001b[0m\u001b[32m(\u001b[0m\u001b[32m^Hi6el\u001b[0m\u001b[32m(\u001b[0m\u001b[32mh1Gdw;f*4\"$b3e+K;_EDp:Rvh,/!T\u001b[0m\n", + "\u001b[32mC\u001b[0m\u001b[32m}\u001b[0m\u001b[32m!u4o\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m-B\\\\6Eh6\u001b[0m\u001b[32m{\u001b[0m\u001b[32m9qFpw,t\u001b[0m\u001b[32m[\u001b[0m\u001b[32m`:y;gOTt22VvnR;\u001b[0m\u001b[32m[\u001b[0m\u001b[32mkX_02kE-#R8iJ.8zJbt>\\\\.FW/>\\'QBTtqyym\u001b[0m\u001b[32m]\u001b[0m\u001b[32mRa4\\'>;\\'imC_zF14Ks`BE@k_NA \u001b[0m\n", + "\u001b[32mBq*_Q9~Q>hv33+ktfKk|;+k|?GMcF~>z6\u001b[0m\u001b[32m]\u001b[0m\u001b[32mj&$7Cb\u001b[0m\u001b[32m{\u001b[0m\u001b[32mA\u001b[0m\u001b[32m}\u001b[0m\u001b[32m,#P.Lw\u001b[0m\u001b[32m]\u001b[0m\u001b[32mAl1lU\\':Ig3Q*Ezm8I4\\'|RoR9K-vRf+yN\u001b[0m\u001b[32m]\u001b[0m\u001b[32m8`\u001b[0m\u001b[32mPYO0G\u001b[0m\u001b[32m=\u001b[0m\u001b[32m7BWxLDr2kQ4\u001b[0m\u001b[32m`4lZ!,jW;YY\u001b[0m\n", + "\u001b[32m38eUep*UOV~0@z#$N*3PldH0solD7Q^lu\\\\$RSJ\u001b[0m\u001b[32m[\u001b[0m\u001b[32mO*3\u001b[0m\u001b[32m)\u001b[0m\u001b[32mB$C\u001b[0m\u001b[32m{\u001b[0m\u001b[32m8oK_\u001b[0m\u001b[32m]\u001b[0m\u001b[32mU6#Kd\u001b[0m\u001b[32m}\u001b[0m\u001b[32m1\u001b[0m\u001b[32m)\u001b[0m\u001b[32mpZ?Doqm8J#`QDK*H2:I8ex\u001b[0m\u001b[32m]\u001b[0m\u001b[32mg1\u001b[0m\u001b[32m[\u001b[0m\u001b[32m,DT\"#:ZpEW_\u001b[0m\u001b[32m)\u001b[0m\u001b[32mJk>C\\'mA\u001b[0m\u001b[32m{\u001b[0m\u001b[32m0IJ\u001b[0m\u001b[32m{\u001b[0m\u001b[32mB6+\u001b[0m\n", + "\u001b[32mZ>yIDB#HC@%KMMJ?\u001b[0m\u001b[32mb\u001b[0m\u001b[32m=`r6X\u001b[0m\u001b[32m)\u001b[0m\u001b[32mM\"`eyvUs`&XL\u001b[0m\u001b[32m{\u001b[0m\u001b[32mxRW;\\'s4S\u001b[0m\u001b[32m<\u001b[0m\u001b[32mAlf9or39ZM\u001b[0m\u001b[32m~#:YB5HNNw9CxIhA\u001b[0m\u001b[32m}\u001b[0m\u001b[32m6``\u001b[0m\u001b[32mj7\u001b[0m\u001b[32m=\u001b[0m\u001b[32mGS7LE1zH8\u001b[0m\u001b[32m;|7y*^Gal/>8B\\\\l$c|\\\\9~B@&j\u001b[0m\n", + "\u001b[32ma\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\yKa#qL\u001b[0m\u001b[32m)\u001b[0m\u001b[32m@/#y\u001b[0m\u001b[32m}\u001b[0m\u001b[32mO43&iMBC\u001b[0m\u001b[32m{\u001b[0m\u001b[32m0E&ta\u001b[0m\u001b[32m{\u001b[0m\u001b[32m`R7`>^&*\u001b[0m\u001b[32m}\u001b[0m\u001b[32mbA18$tNQGiVPWl\u001b[0m\u001b[32m[\u001b[0m\u001b[32m(\u001b[0m\u001b[32mBlp\u001b[0m\u001b[32m{\u001b[0m\u001b[32m3JA$\u001b[0m\u001b[32mDv\u001b[0m\u001b[32m=\u001b[0m\u001b[32mpPMMGP\u001b[0m\u001b[32m,rF~O\\x0cRMfxAYpC!L?-~>T`sM?\\'*LB\\x0cHhODokB5Z@Z21kfc4w&\u001b[0m\u001b[32m}\u001b[0m\u001b[32mt3\u001b[0m\u001b[32m}\u001b[0m\u001b[32m8F|A.3\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\rNgwdgEI7*cY\"ii-Dk8u4ZaG\u001b[0m\u001b[32m(\u001b[0m\u001b[32mC/pD\u001b[0m\n", + "\u001b[32m}\u001b[0m\u001b[32mX!|Cp&hu*/S5\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\\\l@U&:=?1_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mHX\u001b[0m\u001b[32m(\u001b[0m\u001b[32mum_.x9X+J.i81snKUZnMt_Lb4hsg|@_$wp+D3a,~?0vw\\'JW4O#xrllcY\u001b[0m\u001b[32m}\u001b[0m\u001b[32mWlRA?lzEhsoR3kE,d\\'\"X~N`4;hT\u001b[0m\n", + "\u001b[32m0*\\x0bGaXM\u001b[0m\u001b[32m{\u001b[0m\u001b[32m8\u001b[0m\u001b[32m=\u001b[0m\u001b[32mN\u001b[0m\u001b[32m+d\u001b[0m\u001b[32m)\u001b[0m\u001b[32m[\u001b[0m\u001b[32m#65\"d\u001b[0m\u001b[32m]\u001b[0m\u001b[32m+.9Bg;X_JU\u001b[0m\u001b[32m[\u001b[0m\u001b[32mG/1JHA@@|#*Z\u001b[0m\u001b[32m)\u001b[0m\u001b[32m3J38f\u001b[0m\u001b[32m)\u001b[0m\u001b[32mDmcE:+/\\x0cHL`Eq*5c#G\u001b[0m\u001b[32m}\u001b[0m\u001b[32mf`EXDMPd-Mh5%5_:J\u001b[0m\u001b[32m)\u001b[0m\u001b[32mj+;n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mql`eTyoz-CR^cA-FlCii\"fp~5u`?D$Z\u001b[0m\u001b[32m(\u001b[0m\u001b[32ma@r9iY\u001b[0m\u001b[32meg\u001b[0m\u001b[32m=\u001b[0m\u001b[32mH\u001b[0m\u001b[32m!_z`8\u001b[0m\u001b[32m{\u001b[0m\u001b[32mWcb7Xg+9t\u001b[0m\n", + "\u001b[32mv@8qv7?M7,.>e\u001b[0m\u001b[32m}\u001b[0m\u001b[32mKfvqmKK9\\'ZdhB;*3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m<0,R+Jlt3.\u001b[0m\u001b[32mgo3\u001b[0m\u001b[32m=\u001b[0m\u001b[32mUK\u001b[0m\u001b[32m\\'yj\\'\u001b[0m\u001b[32mZ\u001b[0m\u001b[32m==\u001b[0m\u001b[32m[\u001b[0m\u001b[32mdOwSe\u001b[0m\u001b[32m]\u001b[0m\u001b[32ms\u001b[0m\u001b[32m(\u001b[0m\u001b[32mshfX\u001b[0m\u001b[32m(\u001b[0m\u001b[32m{\u001b[0m\u001b[32m4~4efq~\u001b[0m\n", + "\u001b[32m5j+;_R\u001b[0m\u001b[32m(\u001b[0m\u001b[32mt,H-q,-\\x0bN_/*MiPKOlE\u001b[0m\u001b[32m)\u001b[0m\u001b[32mab0wg\\rAYAJc7JY^l3\u001b[0m\u001b[32m{\u001b[0m\u001b[32m+9AA\u001b[0m\u001b[32m]\u001b[0m\u001b[32m~J-\u001b[0m\u001b[32m(\u001b[0m\u001b[32mi6\u001b[0m\u001b[32m[\u001b[0m\u001b[32m>/am\u001b[0m\u001b[32m{\u001b[0m\u001b[32mT\u001b[0m\u001b[32m)\u001b[0m\u001b[32m*=:9TZ\u001b[0m\u001b[32m)\u001b[0m\n", + "\u001b[32mhMyg\u001b[0m\u001b[32m(\u001b[0m\u001b[32mW4B61Y5\\\\\\\\R_lRT&$C|19TY#\u001b[0m\u001b[32m{\u001b[0m\u001b[32mF!8^\\\\N%b\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\'J?EQoH6@\u001b[0m\u001b[32m)\u001b[0m\u001b[32m@^zeO\">\u001b[0m\u001b[32m[\u001b[0m\u001b[32mA@F6/DA/1:\u001b[0m\u001b[32m)\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32mz#K7%|GN/|s;0~rPemA\u001b[0m\u001b[32m(\u001b[0m\u001b[32m{\u001b[0m\u001b[32m6S\"y\u001b[0m\u001b[32m(\u001b[0m\u001b[32m{\u001b[0m\u001b[32m_Hs@9ON>r0cm\\x0cHeL\\'\\'l~>W?DW\".\u001b[0m\u001b[32mkEdz\u001b[0m\u001b[32m=\u001b[0m\u001b[32mYn1\u001b[0m\n", + "\u001b[32mE5m\u001b[0m\u001b[32m=IelWe2k-SP\"|=;\u001b[0m\u001b[32m(\u001b[0m\u001b[32m|\u001b[0m\u001b[32m[\u001b[0m\u001b[32m=WG2qI\\nYdihR~Dr45%Y@\u001b[0m\u001b[32mK\u001b[0m\u001b[32m=\u001b[0m\u001b[32m[\u001b[0m\u001b[32mk%g%2$c^xPUbxW*lzVHW@G_ymLo1i\\x0cLAKPz@Y;cc\"iSBiCHM0S\u001b[0m\u001b[32m)\u001b[0m\u001b[32m/:>M\u001b[0m\u001b[32m{\u001b[0m\u001b[32m%?zeP5_8*\u001b[0m\u001b[32mN_\u001b[0m\n", + "\u001b[32mijWjS2Pw\u001b[0m\u001b[32m=$9\";xE2D;>4-*%XP!3\\'Ggc\u001b[0m\u001b[32m(\u001b[0m\u001b[32mERo\\'b*Jt\u001b[0m\u001b[32m}\u001b[0m\u001b[32m:uvSDL\u001b[0m\u001b[32m(\u001b[0m\u001b[32m/ \u001b[0m\n", + "\u001b[32mO5s+oyIEoBA%WYA^DAc30aj9fsc\\\\gh\\\\B\u001b[0m\u001b[32m[\u001b[0m\u001b[32mxKOrT&%|pg\\x0bOW?wUJOngrPag,&7t4%\\'#\u001b[0m\u001b[32m}\u001b[0m\u001b[32m?1JA+z\u001b[0m\u001b[32m]\u001b[0m\u001b[32mFIu\\'\u001b[0m\u001b[32m(\u001b[0m\u001b[32mJDC\u001b[0m\u001b[32m{\u001b[0m\u001b[32mkW4\u001b[0m\u001b[32m)\u001b[0m\u001b[32mGSsq\u001b[0m\u001b[32m[\u001b[0m\u001b[32myzZ?6\\'=\u001b[0m\u001b[32m)\u001b[0m\u001b[32m5Z\u001b[0m\u001b[32m]\u001b[0m\u001b[32mE\u001b[0m\u001b[32m=\u001b[0m\u001b[32m4\u001b[0m\u001b[32m=\u001b[0m\u001b[32m_\u001b[0m\n", + "\u001b[32mW0eIeebu\u001b[0m\u001b[32m=\u001b[0m\u001b[32m8\"\u001b[0m\u001b[32m~uhQ\\\\LA%Hh~*T4~\"t!EZ#pNn?:J#s4VVI\u001b[0m\u001b[32m)\u001b[0m\u001b[32mfE \u001b[0m\n", + "\u001b[32mA660O\u001b[0m\u001b[32m)\u001b[0m\u001b[32mGO$B6*,J\"9+Dd-Yx\\\\P2cTIVe,t%qvs*@h\u001b[0m\u001b[32m]\u001b[0m\u001b[32mwMSYG19,Ww6E4aR44Sat1PF$\u001b[0m\u001b[32m{\u001b[0m\u001b[32mOG@%,.33A-p9G\u001b[0m\u001b[32m[\u001b[0m\u001b[32mQ#sRWZf?7Z0!_v\u001b[0m\u001b[32m]\u001b[0m\u001b[32mv$+qzkp^\u001b[0m\u001b[32mrD\u001b[0m\u001b[32m=.:E#yUg\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\n", + "\u001b[32myXw+/bJp@9l\\'z\u001b[0m\u001b[32m]\u001b[0m\u001b[32mGG%hPk!J!\u001b[0m\u001b[32m]\u001b[0m\u001b[32m$*Ez*kR\u001b[0m\u001b[32m]\u001b[0m\u001b[32m%n;H\\\\\\'c&~q\u001b[0m\u001b[32m,#?^p;:.ADr\u001b[0m\u001b[32m)\u001b[0m\u001b[32m$vv\"Ddb9wV_p--,\u001b[0m\u001b[32m(\u001b[0m\u001b[32m7/E$\u001b[0m\u001b[32m(\u001b[0m\u001b[32m)\u001b[0m\u001b[32mO`jZ\\rWah00;;/9|bou3$*4Uo/y\u001b[0m\u001b[32m)\u001b[0m\u001b[32mTc8\u001b[0m\u001b[32m]\u001b[0m\u001b[32m]\u001b[0m\u001b[32mSK@,$L\\'\u001b[0m\n", + "\u001b[32mOdL!$Q?!~=j\\'kB\\'L42@nj\u001b[0m\u001b[32m]\u001b[0m\u001b[32m$V:9XY^\u001b[0m\u001b[32m[\u001b[0m\u001b[32muQwh*\u001b[0m\u001b[32mF\u001b[0m\u001b[32m=%z&L,&:@1I'\u001b[0m,\n", + " \u001b[33merror_spans\u001b[0m=\u001b[3;35mNone\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;36m25\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m19\u001b[0m, \u001b[1;36m56\u001b[0m, \u001b[1;36m81461\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;36m25\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m19\u001b[0m, \u001b[1;36m56\u001b[0m, \u001b[1;36m94752\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.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/json_function_calling_tools.ipynb b/docs/examples/json_function_calling_tools.ipynb new file mode 100644 index 000000000..d47f414d0 --- /dev/null +++ b/docs/examples/json_function_calling_tools.ipynb @@ -0,0 +1,989 @@ +{ + "cells": [ + { + "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": 5, + "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": 3, + "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.add_json_function_calling_tool([])\n", + "\n", + "print(pydantic_guard_tools)" + ] + }, + { + "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",
+       "                'properties': {\n",
+       "                    'deliveries': {\n",
+       "                        'items': {\n",
+       "                            'properties': {\n",
+       "                                'customer_name': {'type': 'string', 'description': 'customer name'},\n",
+       "                                'pickup_time': {'type': 'string', 'description': 'date and time of pickup'},\n",
+       "                                'pickup_location': {'type': 'string', 'description': 'address of pickup'},\n",
+       "                                'dropoff_time': {'type': 'string', 'description': 'date and time of dropoff'},\n",
+       "                                'dropoff_location': {'type': 'string', 'description': 'address of dropoff'},\n",
+       "                                'price': {\n",
+       "                                    'type': 'string',\n",
+       "                                    'description': 'price of delivery with currency symbol included'\n",
+       "                                }\n",
+       "                            },\n",
+       "                            'required': [\n",
+       "                                'customer_name',\n",
+       "                                'pickup_time',\n",
+       "                                'pickup_location',\n",
+       "                                'dropoff_time',\n",
+       "                                'dropoff_location',\n",
+       "                                'price'\n",
+       "                            ],\n",
+       "                            'type': 'object'\n",
+       "                        },\n",
+       "                        'type': 'array'\n",
+       "                    }\n",
+       "                },\n",
+       "                'required': ['deliveries'],\n",
+       "                'type': 'object'\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'properties'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'deliveries'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'items'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'properties'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'customer_name'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m, \u001b[32m'description'\u001b[0m: \u001b[32m'customer name'\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[32m'pickup_time'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m, \u001b[32m'description'\u001b[0m: \u001b[32m'date and time of pickup'\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[32m'pickup_location'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m, \u001b[32m'description'\u001b[0m: \u001b[32m'address of pickup'\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[32m'dropoff_time'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m, \u001b[32m'description'\u001b[0m: \u001b[32m'date and time of dropoff'\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[32m'dropoff_location'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m, \u001b[32m'description'\u001b[0m: \u001b[32m'address of dropoff'\u001b[0m\u001b[1m}\u001b[0m,\n", + " \u001b[32m'price'\u001b[0m: \u001b[1m{\u001b[0m\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'string'\u001b[0m,\n", + " \u001b[32m'description'\u001b[0m: \u001b[32m'price of delivery with currency symbol included'\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'customer_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'type'\u001b[0m: \u001b[32m'object'\u001b[0m\n", + " \u001b[1m}\u001b[0m,\n", + " \u001b[32m'type'\u001b[0m: \u001b[32m'array'\u001b[0m\n", + " \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[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": [ + "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.add_json_function_calling_tool([])\n", + "\n", + "print(rail_guard_tools)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='4801405536',\n",
+       "    raw_llm_output='{\"deliveries\": [{\"customer_name\": \"Nelson Murdock\", \"pickup_time\": \"2022-01-15T10:00:00\", \n",
+       "\"pickup_location\": \"123 Main Street\", \"dropoff_time\": \"2022-01-15T12:00:00\", \"dropoff_location\": \"456 Elm Street\", \n",
+       "\"price\": \"$50\"}, {\"customer_name\": \"Abc Flowers\", \"pickup_time\": \"2022-01-16T11:00:00\", \"pickup_location\": \"456 Oak\n",
+       "Avenue\", \"dropoff_time\": \"2022-01-16T13:00:00\", \"dropoff_location\": \"789 Pine Road\", \"price\": \"$60\"}, \n",
+       "{\"customer_name\": \"Polk Wardell\", \"pickup_time\": \"2022-01-17T09:00:00\", \"pickup_location\": \"789 Maple Lane\", \n",
+       "\"dropoff_time\": \"2022-01-17T11:00:00\", \"dropoff_location\": \"234 Birch Boulevard\", \"price\": \"$70\"}]}',\n",
+       "    validated_output={\n",
+       "        'deliveries': [\n",
+       "            {\n",
+       "                'customer_name': 'Nelson 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",
+       "                'customer_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",
+       "                'customer_name': 'Polk 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=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'4801405536'\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\"customer_name\": \"Nelson Murdock\", \"pickup_time\": \"2022-01-15T10:00:00\", \u001b[0m\n", + "\u001b[32m\"pickup_location\": \"123 Main Street\", \"dropoff_time\": \"2022-01-15T12:00:00\", \"dropoff_location\": \"456 Elm Street\", \u001b[0m\n", + "\u001b[32m\"price\": \"$50\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"customer_name\": \"Abc Flowers\", \"pickup_time\": \"2022-01-16T11:00:00\", \"pickup_location\": \"456 Oak\u001b[0m\n", + "\u001b[32mAvenue\", \"dropoff_time\": \"2022-01-16T13:00:00\", \"dropoff_location\": \"789 Pine Road\", \"price\": \"$60\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\n", + "\u001b[32m{\u001b[0m\u001b[32m\"customer_name\": \"Polk Wardell\", \"pickup_time\": \"2022-01-17T09:00:00\", \"pickup_location\": \"789 Maple Lane\", \u001b[0m\n", + "\u001b[32m\"dropoff_time\": \"2022-01-17T11:00:00\", \"dropoff_location\": \"234 Birch Boulevard\", \"price\": \"$70\"\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'customer_name'\u001b[0m: \u001b[32m'Nelson 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'customer_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'customer_name'\u001b[0m: \u001b[32m'Polk 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;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 openai\n", + "\n", + "response = rail_guard(\n", + " openai.chat.completions.create,\n", + " model=\"gpt-3.5-turbo\",\n", + " instructions=\"You are a helpful assistant.\",\n", + " prompt=prompt,\n", + " prompt_params={\"chat_history\": chat_history},\n", + " tools=rail_guard_tools,\n", + " tool_choice=\"required\",\n", + ")\n", + "\n", + "print(response)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "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\":[{\"customer_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\"},{\"customer_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\"},{\"customer_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",
+       "│   │ │             'customer_name': FieldReAsk(                                                                │ │\n",
+       "│   │ │                 incorrect_value='nelson and murdock',                                                   │ │\n",
+       "│   │ │                 fail_results=[                                                                          │ │\n",
+       "│   │ │                     FailResult(                                                                         │ │\n",
+       "│   │ │                         outcome='fail',                                                                 │ │\n",
+       "│   │ │                         error_message='Result must match ^[A-Z]+\\\\s[A-Z]+$',                            │ │\n",
+       "│   │ │                         fix_value='Rdbuqatcsperioirtnincsfincsctvizmazkylbbhmrenbdyzkjeogozpyoiyvopuegv │ │\n",
+       "│   │ │ vudra\\x0cShvihshzagoeniiawwdumtstqwhanryigafmqrfulfwelkuaozbtuvwycgcjwxxvqbawhqvclb',                   │ │\n",
+       "│   │ │                         error_spans=None,                                                               │ │\n",
+       "│   │ │                         metadata=None,                                                                  │ │\n",
+       "│   │ │                         validated_chunk=None                                                            │ │\n",
+       "│   │ │                     )                                                                                   │ │\n",
+       "│   │ │                 ],                                                                                      │ │\n",
+       "│   │ │                 additional_properties={},                                                               │ │\n",
+       "│   │ │                 path=['deliveries', 0, 'customer_name']                                                 │ │\n",
+       "│   │ │             ),                                                                                          │ │\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",
+       "│   │ │             'customer_name': FieldReAsk(                                                                │ │\n",
+       "│   │ │                 incorrect_value='abc flowers',                                                          │ │\n",
+       "│   │ │                 fail_results=[                                                                          │ │\n",
+       "│   │ │                     FailResult(                                                                         │ │\n",
+       "│   │ │                         outcome='fail',                                                                 │ │\n",
+       "│   │ │                         error_message='Result must match ^[A-Z]+\\\\s[A-Z]+$',                            │ │\n",
+       "│   │ │                         fix_value='Gzlawzbrtphaiwzdthhmmxiwwykhqnrsladoovnoryhvwazvhrqjzazeihkfplevvnej │ │\n",
+       "│   │ │ rqurkwin\\x0cMprzjamtwmz',                                                                               │ │\n",
+       "│   │ │                         error_spans=None,                                                               │ │\n",
+       "│   │ │                         metadata=None,                                                                  │ │\n",
+       "│   │ │                         validated_chunk=None                                                            │ │\n",
+       "│   │ │                     )                                                                                   │ │\n",
+       "│   │ │                 ],                                                                                      │ │\n",
+       "│   │ │                 additional_properties={},                                                               │ │\n",
+       "│   │ │                 path=['deliveries', 1, 'customer_name']                                                 │ │\n",
+       "│   │ │             ),                                                                                          │ │\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",
+       "│   │ │             'customer_name': FieldReAsk(                                                                │ │\n",
+       "│   │ │                 incorrect_value='polk and wardell',                                                     │ │\n",
+       "│   │ │                 fail_results=[                                                                          │ │\n",
+       "│   │ │                     FailResult(                                                                         │ │\n",
+       "│   │ │                         outcome='fail',                                                                 │ │\n",
+       "│   │ │                         error_message='Result must match ^[A-Z]+\\\\s[A-Z]+$',                            │ │\n",
+       "│   │ │                         fix_value='Rcznucwiwovoqjszkwmwbwtepefflvbeciylxkjkxdybjadslmdykapacufjpgolktvq │ │\n",
+       "│   │ │ lbsydhuqfzygsvckomowxbjwnnqzhy\\tXutiwlnafoyguxexopjwoxilwea',                                           │ │\n",
+       "│   │ │                         error_spans=None,                                                               │ │\n",
+       "│   │ │                         metadata=None,                                                                  │ │\n",
+       "│   │ │                         validated_chunk=None                                                            │ │\n",
+       "│   │ │                     )                                                                                   │ │\n",
+       "│   │ │                 ],                                                                                      │ │\n",
+       "│   │ │                 additional_properties={},                                                               │ │\n",
+       "│   │ │                 path=['deliveries', 2, 'customer_name']                                                 │ │\n",
+       "│   │ │             ),                                                                                          │ │\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",
+       "└── ╭────────────────────────────────────────────────── Step 1 ───────────────────────────────────────────────────╮\n",
+       "    │ ╭──────────────────────────────────────────────── Prompt ─────────────────────────────────────────────────╮ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ I was given the following JSON response, which had problems due to incorrect values.                    │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │   \"deliveries\": [                                                                                       │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"customer_name\": {                                                                                │ │\n",
+       "    │ │         \"incorrect_value\": \"nelson and murdock\",                                                        │ │\n",
+       "    │ │         \"error_messages\": [                                                                             │ │\n",
+       "    │ │           \"Result must match ^[A-Z]+\\\\s[A-Z]+$\"                                                         │ │\n",
+       "    │ │         ]                                                                                               │ │\n",
+       "    │ │       }                                                                                                 │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"customer_name\": {                                                                                │ │\n",
+       "    │ │         \"incorrect_value\": \"abc flowers\",                                                               │ │\n",
+       "    │ │         \"error_messages\": [                                                                             │ │\n",
+       "    │ │           \"Result must match ^[A-Z]+\\\\s[A-Z]+$\"                                                         │ │\n",
+       "    │ │         ]                                                                                               │ │\n",
+       "    │ │       }                                                                                                 │ │\n",
+       "    │ │     },                                                                                                  │ │\n",
+       "    │ │     {                                                                                                   │ │\n",
+       "    │ │       \"customer_name\": {                                                                                │ │\n",
+       "    │ │         \"incorrect_value\": \"polk and wardell\",                                                          │ │\n",
+       "    │ │         \"error_messages\": [                                                                             │ │\n",
+       "    │ │           \"Result must match ^[A-Z]+\\\\s[A-Z]+$\"                                                         │ │\n",
+       "    │ │         ]                                                                                               │ │\n",
+       "    │ │       }                                                                                                 │ │\n",
+       "    │ │     }                                                                                                   │ │\n",
+       "    │ │   ]                                                                                                     │ │\n",
+       "    │ │ }                                                                                                       │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Help me correct the incorrect values based on the given error messages.                                 │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Given below is a JSON Schema that describes the output structure you should return.                     │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ {\"properties\": {\"deliveries\": {\"items\": {\"properties\": {\"customer_name\": {\"type\": \"string\",             │ │\n",
+       "    │ │ \"description\": \"customer name\"}, \"pickup_time\": {\"type\": \"string\", \"description\": \"date and time of     │ │\n",
+       "    │ │ pickup\"}, \"pickup_location\": {\"type\": \"string\", \"description\": \"address of pickup\"}, \"dropoff_time\":    │ │\n",
+       "    │ │ {\"type\": \"string\", \"description\": \"date and time of dropoff\"}, \"dropoff_location\": {\"type\": \"string\",   │ │\n",
+       "    │ │ \"description\": \"address of dropoff\"}, \"price\": {\"type\": \"string\", \"description\": \"price of delivery     │ │\n",
+       "    │ │ with currency symbol included\"}}, \"required\": [\"customer_name\", \"pickup_time\", \"pickup_location\",       │ │\n",
+       "    │ │ \"dropoff_time\", \"dropoff_location\", \"price\"], \"type\": \"object\"}, \"type\": \"array\"}}, \"required\":         │ │\n",
+       "    │ │ [\"deliveries\"], \"type\": \"object\"}                                                                       │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ ONLY return a valid JSON object (no other text is necessary), where the key of the field in the JSON is │ │\n",
+       "    │ │ the key of the entries within the schema's `properties`, and the value is of the type specified by the  │ │\n",
+       "    │ │ `type` property under that key.                                                                         │ │\n",
+       "    │ │ The JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A JSON   │ │\n",
+       "    │ │ Schema ITSELF.                                                                                          │ │\n",
+       "    │ │ Be sure to include any types and format requests e.g. requests for lists, objects and specific types.   │ │\n",
+       "    │ │ Be correct and concise.                                                                                 │ │\n",
+       "    │ │ If you are unsure anywhere, 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). The JSON MUST conform to the JSON Schema  │ │\n",
+       "    │ │ provided, including any types and format requests e.g. requests for lists, objects and specific types.  │ │\n",
+       "    │ │ Be correct and concise. If you are unsure anywhere, enter `null`.                                       │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ │ Here are examples of simple (JSON Schema, JSON) pairs that show the expected behavior:                  │ │\n",
+       "    │ │ - `{\"type\":\"object\",\"properties\":{\"foo\":{\"type\":\"string\",\"format\":\"two-words lower-case\"}}}` =>         │ │\n",
+       "    │ │ `{'foo': 'example one'}`                                                                                │ │\n",
+       "    │ │ -                                                                                                       │ │\n",
+       "    │ │ `{\"type\":\"object\",\"properties\":{\"bar\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"format\":\"upper-case\"}}} │ │\n",
+       "    │ │ }` => `{\"bar\": ['STRING ONE', 'STRING TWO']}`                                                           │ │\n",
+       "    │ │ -                                                                                                       │ │\n",
+       "    │ │ `{\"type\":\"object\",\"properties\":{\"baz\":{\"type\":\"object\",\"properties\":{\"foo\":{\"type\":\"string\",\"format\":\"c │ │\n",
+       "    │ │ apitalize two-words\"},\"index\":{\"type\":\"integer\",\"format\":\"1-indexed\"}}}}}` => `{'baz': {'foo': 'Some    │ │\n",
+       "    │ │ String', 'index': 1}}`                                                                                  │ │\n",
+       "    │ │ -                                                                                                       │ │\n",
+       "    │ │ `{\"type\":\"object\",\"properties\":{\"bar\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"format\":\"upper-case\"}}, │ │\n",
+       "    │ │ \"baz\":{\"type\":\"object\",\"properties\":{\"foo\":{\"type\":\"string\",\"format\":\"two-words lower-case\"}}}}}` =>    │ │\n",
+       "    │ │ `{'bar': ['STRING ONE', 'STRING TWO'], 'baz': {'foo': 'example one'}}`                                  │ │\n",
+       "    │ │                                                                                                         │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Message History ────────────────────────────────────────────╮ │\n",
+       "    │ │ No message history.                                                                                     │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭──────────────────────────────────────────── Raw LLM Output ─────────────────────────────────────────────╮ │\n",
+       "    │ │ {\"deliveries\": [{\"customer_name\": \"Nelson Murdock\", \"pickup_time\": \"2022-01-15T10:00:00\",               │ │\n",
+       "    │ │ \"pickup_location\": \"123 Main Street\", \"dropoff_time\": \"2022-01-15T12:00:00\", \"dropoff_location\": \"456   │ │\n",
+       "    │ │ Elm Street\", \"price\": \"$50\"}, {\"customer_name\": \"Abc Flowers\", \"pickup_time\": \"2022-01-16T11:00:00\",    │ │\n",
+       "    │ │ \"pickup_location\": \"456 Oak Avenue\", \"dropoff_time\": \"2022-01-16T13:00:00\", \"dropoff_location\": \"789    │ │\n",
+       "    │ │ Pine Road\", \"price\": \"$60\"}, {\"customer_name\": \"Polk Wardell\", \"pickup_time\": \"2022-01-17T09:00:00\",    │ │\n",
+       "    │ │ \"pickup_location\": \"789 Maple Lane\", \"dropoff_time\": \"2022-01-17T11:00:00\", \"dropoff_location\": \"234    │ │\n",
+       "    │ │ Birch Boulevard\", \"price\": \"$70\"}]}                                                                     │ │\n",
+       "    │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │\n",
+       "    │ ╭─────────────────────────────────────────── Validated Output ────────────────────────────────────────────╮ │\n",
+       "    │ │ {                                                                                                       │ │\n",
+       "    │ │     'deliveries': [                                                                                     │ │\n",
+       "    │ │         {                                                                                               │ │\n",
+       "    │ │             'customer_name': 'Nelson 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",
+       "    │ │             'customer_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",
+       "    │ │             'customer_name': 'Polk 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\":[{\"customer_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\"},{\"customer_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\"},{\"customer_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 'customer_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='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 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 ^[A-Z]\u001b[0m\u001b[48;2;240;255;240m+\\\\s[A-Z]\u001b[0m\u001b[48;2;240;255;240m+$',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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='Rdbuqatcsperioirtnincsfincsctvizmazkylbbhmrenbdyzkjeogozpyoiyvopuegv\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mvudra\\x0cShvihshzagoeniiawwdumtstqwhanryigafmqrfulfwelkuaozbtuvwycgcjwxxvqbawhqvclb',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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=['deliveries', 0, 'customer_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 '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 'customer_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='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 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 ^[A-Z]\u001b[0m\u001b[48;2;240;255;240m+\\\\s[A-Z]\u001b[0m\u001b[48;2;240;255;240m+$',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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='Gzlawzbrtphaiwzdthhmmxiwwykhqnrsladoovnoryhvwazvhrqjzazeihkfplevvnej\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mrqurkwin\\x0cMprzjamtwmz',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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=['deliveries', 1, 'customer_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 '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 'customer_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='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 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 ^[A-Z]\u001b[0m\u001b[48;2;240;255;240m+\\\\s[A-Z]\u001b[0m\u001b[48;2;240;255;240m+$',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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='Rcznucwiwovoqjszkwmwbwtepefflvbeciylxkjkxdybjadslmdykapacufjpgolktvq\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[0m │\n", + "│ │ \u001b[48;2;240;255;240m│\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240mlbsydhuqfzygsvckomowxbjwnnqzhy\\tXutiwlnafoyguxexopjwoxilwea',\u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m \u001b[0m\u001b[48;2;240;255;240m│\u001b[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=['deliveries', 2, 'customer_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 '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", + "└── ╭────────────────────────────────────────────────── 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 \"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;255m {\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"customer_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\": \"nelson and murdock\",\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[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 \"Result must match ^[A-Z]\u001b[0m\u001b[48;2;240;248;255m+\\\\s[A-Z]\u001b[0m\u001b[48;2;240;248;255m+$\"\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m ]\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m }\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m },\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m {\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"customer_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\": \"abc flowers\",\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[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 \"Result must match ^[A-Z]\u001b[0m\u001b[48;2;240;248;255m+\\\\s[A-Z]\u001b[0m\u001b[48;2;240;248;255m+$\"\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m ]\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m }\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m },\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m {\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \"customer_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\": \"polk and wardell\",\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[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 \"Result must match ^[A-Z]\u001b[0m\u001b[48;2;240;248;255m+\\\\s[A-Z]\u001b[0m\u001b[48;2;240;248;255m+$\"\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m ]\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m }\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m }\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m ]\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m}\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 a JSON Schema that describes the output structure you should return.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\"properties\": {\"deliveries\": {\"items\": {\"properties\": {\"customer_name\": {\"type\": \"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\"description\": \"customer name\"}, \"pickup_time\": {\"type\": \"string\", \"description\": \"date and time 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;255mpickup\"}, \"pickup_location\": {\"type\": \"string\", \"description\": \"address of pickup\"}, \"dropoff_time\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m{\"type\": \"string\", \"description\": \"date and time of dropoff\"}, \"dropoff_location\": {\"type\": \"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\"description\": \"address of dropoff\"}, \"price\": {\"type\": \"string\", \"description\": \"price of delivery \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 currency symbol included\"}}, \"required\": [\"customer_name\", \"pickup_time\", \"pickup_location\", \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m\"dropoff_time\", \"dropoff_location\", \"price\"], \"type\": \"object\"}, \"type\": \"array\"}}, \"required\": \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m[\"deliveries\"], \"type\": \"object\"}\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\u001b[0m │\n", + " │ \u001b[48;2;240;248;255m│\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 the JSON is\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 key of the entries within the schema's `properties`, and the value is of the type specified by 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`type` property under that key. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 JSON MUST conform to the structure described by the JSON Schema provided BUT SHOULD NOT BE A 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;255mSchema ITSELF.\u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 sure to include any types and format requests e.g. requests for lists, objects and specific types. \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m \u001b[0m\u001b[48;2;240;248;255m│\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 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;255mIf you are unsure anywhere, enter `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). The JSON MUST conform to the JSON Schema \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;242mprovided, including any types and format requests e.g. requests for lists, objects and specific types. \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;242mBe correct and concise. If you are unsure anywhere, enter `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 (JSON Schema, 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- `{\"type\":\"object\",\"properties\":{\"foo\":{\"type\":\"string\",\"format\":\"two-words lower-case\"}}}` => \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- \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`{\"type\":\"object\",\"properties\":{\"bar\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"format\":\"upper-case\"}}}\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;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;242m`{\"type\":\"object\",\"properties\":{\"baz\":{\"type\":\"object\",\"properties\":{\"foo\":{\"type\":\"string\",\"format\":\"c\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;242mapitalize two-words\"},\"index\":{\"type\":\"integer\",\"format\":\"1-indexed\"}}}}}` => `{'baz': {'foo': 'Some \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;242mString', '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\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`{\"type\":\"object\",\"properties\":{\"bar\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"format\":\"upper-case\"}},\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\":{\"type\":\"object\",\"properties\":{\"foo\":{\"type\":\"string\",\"format\":\"two-words lower-case\"}}}}}` => \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'], 'baz': {'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 \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\": [{\"customer_name\": \"Nelson Murdock\", \"pickup_time\": \"2022-01-15T10:00:00\", \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m\"pickup_location\": \"123 Main Street\", \"dropoff_time\": \"2022-01-15T12:00:00\", \"dropoff_location\": \"456 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mElm Street\", \"price\": \"$50\"}, {\"customer_name\": \"Abc Flowers\", \"pickup_time\": \"2022-01-16T11:00:00\", \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m\"pickup_location\": \"456 Oak Avenue\", \"dropoff_time\": \"2022-01-16T13:00:00\", \"dropoff_location\": \"789 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mPine Road\", \"price\": \"$60\"}, {\"customer_name\": \"Polk Wardell\", \"pickup_time\": \"2022-01-17T09:00:00\", \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m\"pickup_location\": \"789 Maple Lane\", \"dropoff_time\": \"2022-01-17T11:00:00\", \"dropoff_location\": \"234 \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220m│\u001b[0m │\n", + " │ \u001b[48;2;245;245;220m│\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[48;2;245;245;220mBirch Boulevard\", \"price\": \"$70\"}]}\u001b[0m\u001b[48;2;245;245;220m \u001b[0m\u001b[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 'customer_name': 'Nelson 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 'customer_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 'customer_name': 'Polk 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": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rail_guard.history.last.tree" + ] + } + ], + "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.3" + } + }, + "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..a29073b21 --- /dev/null +++ b/docs/examples/lite_llm_defaults.ipynb @@ -0,0 +1,91 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! guardrails hub install hub://guardrails/regex_match --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
ValidationOutcome(\n",
+       "    call_id='4927013424',\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'4927013424'\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", + "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", + ")\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.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/guardrails/actions/filter.py b/guardrails/actions/filter.py index 8d25dd9ee..e11bb7d5d 100644 --- a/guardrails/actions/filter.py +++ b/guardrails/actions/filter.py @@ -6,6 +6,7 @@ class Filter: 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): diff --git a/guardrails/actions/refrain.py b/guardrails/actions/refrain.py index 923b746d3..a4819cc20 100644 --- a/guardrails/actions/refrain.py +++ b/guardrails/actions/refrain.py @@ -24,6 +24,10 @@ def check_for_refrain(value: Union[List, Dict]) -> bool: # 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 = "" diff --git a/guardrails/classes/validation/validation_result.py b/guardrails/classes/validation/validation_result.py index 316f3c415..d5732570a 100644 --- a/guardrails/classes/validation/validation_result.py +++ b/guardrails/classes/validation/validation_result.py @@ -78,6 +78,17 @@ def to_dict(self) -> Dict[str, Any]: # FIXME: Add this to json schema 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 @@ -89,7 +100,10 @@ class FailResult(ValidationResult, IFailResult): error_message: str fix_value: Optional[Any] = None - # segments that caused validation to fail + """Segments that caused validation to fail. + + May not exist for non-streamed output. + """ error_spans: Optional[List[ErrorSpan]] = None @classmethod diff --git a/guardrails/errors/__init__.py b/guardrails/errors/__init__.py index de9cd519b..d66d5bed0 100644 --- a/guardrails/errors/__init__.py +++ b/guardrails/errors/__init__.py @@ -1,20 +1,11 @@ -# Never actually used in any validators so the description is misleading. -# The naming is confusing so we're updating it. -class ValidatorError(Exception): - """ - deprecated: 0.3.3 - Use :class:`ValidationError` instead. +class ValidationError(Exception): + """Top level validation error. - Base class for all validator errors. + This is thrown from the validation engine when a Validator has + on_fail=OnFailActions.EXCEPTION set and validation fails. """ -# Open to naming this something more generic like GuardrailsError or something, -# let's just decide in this PR -class ValidationError(Exception): - """Top level validation error.""" - - class UserFacingException(Exception): """Wraps an exception to denote it as user-facing. diff --git a/guardrails/guard.py b/guardrails/guard.py index f0a5a6d62..4a0928b21 100644 --- a/guardrails/guard.py +++ b/guardrails/guard.py @@ -31,6 +31,7 @@ from guardrails.api_client import GuardrailsApiClient from guardrails.classes.output_type import OT +from guardrails.classes.validation.validation_result import ErrorSpan from guardrails.classes.validation_outcome import ValidationOutcome from guardrails.classes.credentials import Credentials from guardrails.classes.execution import GuardExecutionOptions @@ -326,7 +327,8 @@ def from_rail( name: Optional[str] = None, description: Optional[str] = None, ): - """Create a Schema from a `.rail` file. + """Create a Guard using a `.rail` file to specify the output schema, + prompt, etc. Args: rail_file: The path to the `.rail` file. @@ -374,7 +376,8 @@ def from_rail_string( name: Optional[str] = None, description: Optional[str] = None, ): - """Create a Schema from a `.rail` string. + """Create a Guard using a `.rail` string to specify the output schema, + prompt, etc.. Args: rail_string: The `.rail` string. @@ -427,7 +430,8 @@ def from_pydantic( description: Optional[str] = None, output_formatter: Optional[Union[str, BaseFormatter]] = None, ): - """Create a Guard instance from a Pydantic model. + """Create a Guard instance using a Pydantic model to specify the output + schema. Args: output_class: (Union[Type[BaseModel], List[Type[BaseModel]]]): The pydantic model that describes @@ -810,7 +814,7 @@ def __call__( `False` otherwise. Returns: - The raw text output from the LLM and the validated output. + ValidationOutcome """ instructions = instructions or self._exec_opts.instructions prompt = prompt or self._exec_opts.prompt @@ -859,8 +863,7 @@ def parse( or just the incorrect values. Returns: - The validated response. This is either a string or a dictionary, - determined by the object schema defined in the RAILspec. + ValidationOutcome """ final_num_reasks = ( num_reasks @@ -894,7 +897,8 @@ def parse( **kwargs, ) - def error_spans_in_output(self): + def error_spans_in_output(self) -> List[ErrorSpan]: + """Get the error spans in the last output.""" try: call = self.history.last if call: @@ -956,8 +960,6 @@ def use( - The instructions - The message history - *Note*: For on="output", `use` is only available for string output types. - Args: validator: The validator to use. Either the class or an instance. on: The part of the LLM request to validate. Defaults to "output". @@ -982,7 +984,7 @@ def use_many( *validators: UseManyValidatorSpec, on: str = "output", ) -> "Guard": - """Use a validator to validate results of an LLM request.""" + """Use multiple validators to validate results of an LLM request.""" # Loop through the validators for v in validators: hydrated_validator = get_validator(v) @@ -1146,6 +1148,7 @@ def _save(self): self.upsert_guard() def to_runnable(self) -> Runnable: + """Convert a Guard to a LangChain Runnable.""" from guardrails.integrations.langchain.guard_runnable import GuardRunnable return GuardRunnable(self) @@ -1167,6 +1170,8 @@ def add_json_function_calling_tool( self, tools: list, ) -> List[Dict[str, Any]]: + """Appends an OpenAI tool that specifies the output structure using + JSON Schema for chat models.""" tools = add_json_function_calling_tool( tools=tools, # todo to_dict has a slight bug workaround here From 7df5c874dbb71274cc0376b5898e898301169398 Mon Sep 17 00:00:00 2001 From: Caleb Courier Date: Wed, 26 Jun 2024 10:56:39 -0500 Subject: [PATCH 3/5] start updating api reference --- docs/pydocs/generate_pydocs.py | 78 ++++++++++++++++++++-------------- guardrails/__init__.py | 2 +- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/docs/pydocs/generate_pydocs.py b/docs/pydocs/generate_pydocs.py index a0e428ad1..b3d28f7ed 100644 --- a/docs/pydocs/generate_pydocs.py +++ b/docs/pydocs/generate_pydocs.py @@ -1,17 +1,19 @@ import os + # from pydoc_markdown.interfaces import Context from docspec_python import ParserOptions 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)): @@ -31,9 +33,9 @@ def write_to_file(str, filename): # ), # ), # processor = FilterProcessor( -# expression="not name.startswith('_') and not name.startswith('load') and default()", +# expression="not name.startswith('_') and not name.startswith('load') and default()", # noqa # documented_only=True, - + # ) # ), # filename="docs/api_reference_markdown/rail.md", @@ -41,29 +43,42 @@ def write_to_file(str, filename): write_to_file( - str="# Guard\n\n" + render_loader( + str="# Guard\n\n" + + render_loader( PythonLoader( - modules=['guardrails.guard'], - parser=ParserOptions( - print_function=False - ), + modules=["guardrails.guard"], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression="name in ['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' 'add_json_function_calling_tool' 'to_dict' 'from_dict' 'to_runnable']", # noqa + skip_empty_modules=True, + ), + ), + filename="docs/api_reference_markdown/guard.md", +) + +write_to_file( + str="# AsyncGuard\n\n" + + render_loader( + PythonLoader( + modules=["guardrails.async_guard"], + parser=ParserOptions(print_function=False), + ), + processor=FilterProcessor( + expression="name in ['AsyncGuard', 'guardrails.async_guard', 'guard', '__init__' 'from_rail' 'from_rail_string' 'from_pydantic' 'from_string' 'configure' 'use' 'use_many' '__call__' 'parse' 'validate' 'error_spans_in_output' 'add_json_function_calling_tool' 'to_dict' 'from_dict' 'to_runnable']", # noqa + skip_empty_modules=True, ), - 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", ) +# FIXME: This isn't a thing anymore; validators have been removed. 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", @@ -71,17 +86,16 @@ def write_to_file(str, filename): write_to_file( # str=class_to_string(ValidationOutcome, ignore_prefix_list=["load", "_"]), - str="# Validation Outcome\n\n" + render_loader( + str="# Validation Outcome\n\n" + + render_loader( PythonLoader( - modules=['guardrails.classes.validation_outcome'], - parser=ParserOptions( - print_function=False - ), + modules=["guardrails.classes.validation_outcome"], + parser=ParserOptions(print_function=False), ), - processor = FilterProcessor( + processor=FilterProcessor( documented_only=True, ), - renderer = MarkdownRenderer( + renderer=MarkdownRenderer( render_module_header=False, insert_header_anchors=False, classdef_code_block=False, @@ -89,7 +103,7 @@ def write_to_file(str, filename): classdef_with_decorators=False, render_typehint_in_data_header=True, data_code_block=True, - ) + ), ), filename="docs/hub/api_reference_markdown/validation_outcome.md", ) @@ -102,7 +116,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 +135,6 @@ def write_to_file(str, filename): # ) - # write_to_file( # str="# Schema\n\n" + render_loader(PythonLoader( # modules=['guardrails.schema'], @@ -159,14 +172,13 @@ def write_to_file(str, filename): # ) write_to_file( - str="# History and Logs\n\n" + render_loader( + str="# History and Logs\n\n" + + render_loader( PythonLoader( - packages=['classes.history'], - parser=ParserOptions( - print_function=False - ), + packages=["classes.history"], + parser=ParserOptions(print_function=False), ), - renderer = MarkdownRenderer( + renderer=MarkdownRenderer( render_module_header=True, insert_header_anchors=False, descriptive_class_title=True, diff --git a/guardrails/__init__.py b/guardrails/__init__.py index dd3bf9b1c..742abecaf 100644 --- a/guardrails/__init__.py +++ b/guardrails/__init__.py @@ -12,7 +12,7 @@ __all__ = [ "Guard", "AsyncGuard", - "PromptCallableBase", + "PromptCallableBase", # FIXME: Why is this being exported? "Validator", "OnFailAction", "register_validator", From 80675f5819167bd33450d9f8eac9218654fa8c60 Mon Sep 17 00:00:00 2001 From: Caleb Courier Date: Mon, 1 Jul 2024 09:59:02 -0500 Subject: [PATCH 4/5] update api reference --- docs/api_reference/actions.md | 4 - docs/api_reference/constants.md | 4 - docs/api_reference/validators.md | 3 - docs/examples/guardrails_server.ipynb | 188 +++++------------- docs/pydocs/api_reference/actions.py | 60 ++++++ docs/pydocs/api_reference/errors.py | 24 +++ docs/pydocs/api_reference/formatters.py | 27 +++ .../generics_and_base_classes.py | 27 +++ docs/pydocs/api_reference/guards.py | 84 ++++++++ docs/pydocs/api_reference/history.py | 22 ++ docs/pydocs/api_reference/llm_interaction.py | 68 +++++++ docs/pydocs/api_reference/types.py | 73 +++++++ docs/pydocs/api_reference/validation.py | 71 +++++++ docs/pydocs/generate_pydocs.py | 121 +---------- docs/pydocs/helpers.py | 10 + docs/pydocs/pydocs_markdown_impl.py | 29 ++- guardrails/actions/reask.py | 27 +++ guardrails/async_guard.py | 4 +- guardrails/call_tracing/__init__.py | 9 +- .../call_tracing/sqlite_trace_handler.py | 50 ++--- guardrails/call_tracing/trace_entry.py | 12 +- guardrails/call_tracing/trace_handler.py | 12 +- guardrails/call_tracing/tracer_mixin.py | 8 +- guardrails/classes/generic/arbitrary_model.py | 2 + guardrails/classes/history/__init__.py | 2 +- guardrails/classes/history/call.py | 14 ++ guardrails/classes/history/call_inputs.py | 15 ++ guardrails/classes/history/inputs.py | 23 +++ guardrails/classes/history/iteration.py | 12 ++ guardrails/classes/history/outputs.py | 23 ++- guardrails/classes/llm/llm_response.py | 15 ++ .../classes/validation/validation_result.py | 68 +++++-- .../classes/validation/validator_logs.py | 15 +- .../classes/validation/validator_reference.py | 19 ++ guardrails/classes/validation_outcome.py | 15 ++ guardrails/errors/__init__.py | 2 + guardrails/formatters/json_formatter.py | 3 + guardrails/guard.py | 17 +- guardrails/llm_providers.py | 4 +- guardrails/prompt/base_prompt.py | 9 +- guardrails/prompt/instructions.py | 2 +- guardrails/prompt/prompt.py | 2 +- guardrails/run/async_stream_runner.py | 13 +- guardrails/run/stream_runner.py | 12 +- guardrails/types/__init__.py | 4 +- guardrails/types/inputs.py | 2 +- guardrails/types/on_fail.py | 17 ++ guardrails/types/rail.py | 19 ++ guardrails/validators/__init__.py | 1 + package.json | 3 +- tests/unit_tests/test_guard_log.py | 3 +- 51 files changed, 916 insertions(+), 357 deletions(-) delete mode 100644 docs/api_reference/actions.md delete mode 100644 docs/api_reference/constants.md delete mode 100644 docs/api_reference/validators.md create mode 100644 docs/pydocs/api_reference/actions.py create mode 100644 docs/pydocs/api_reference/errors.py create mode 100644 docs/pydocs/api_reference/formatters.py create mode 100644 docs/pydocs/api_reference/generics_and_base_classes.py create mode 100644 docs/pydocs/api_reference/guards.py create mode 100644 docs/pydocs/api_reference/history.py create mode 100644 docs/pydocs/api_reference/llm_interaction.py create mode 100644 docs/pydocs/api_reference/types.py create mode 100644 docs/pydocs/api_reference/validation.py create mode 100644 docs/pydocs/helpers.py create mode 100644 guardrails/classes/validation/validator_reference.py diff --git a/docs/api_reference/actions.md b/docs/api_reference/actions.md deleted file mode 100644 index c56c3b0a4..000000000 --- a/docs/api_reference/actions.md +++ /dev/null @@ -1,4 +0,0 @@ - - - -::: guardrails.actions \ No newline at end of file diff --git a/docs/api_reference/constants.md b/docs/api_reference/constants.md deleted file mode 100644 index 7c8ffee4b..000000000 --- a/docs/api_reference/constants.md +++ /dev/null @@ -1,4 +0,0 @@ - - - -::: guardrails.constants \ 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 a6a7263e1..000000000 --- a/docs/api_reference/validators.md +++ /dev/null @@ -1,3 +0,0 @@ - - -::: guardrails.validators \ No newline at end of file diff --git a/docs/examples/guardrails_server.ipynb b/docs/examples/guardrails_server.ipynb index f9d933457..45d346808 100644 --- a/docs/examples/guardrails_server.ipynb +++ b/docs/examples/guardrails_server.ipynb @@ -16,7 +16,7 @@ } ], "source": [ - "! pip install \"guardrails-ai[api]==0.5.0a4\" -q" + "! pip install \"guardrails-ai[api]==0.5.0a9\" -q" ] }, { @@ -28,7 +28,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "/Users/calebcourier/Downloads/demo-050/.venv/bin/guardrails\n" + "/Users/calebcourier/Projects/gr-mono/guardrails/docs/.venv/bin/guardrails\n" ] } ], @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -68,34 +68,16 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": {}, "outputs": [ { - "data": { - "text/html": [ - "
some-token\n",
-       "
\n" - ], - "text/plain": [ - "some-token\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
http://localhost:8000\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[4;94mhttp://localhost:8000\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "some-token\n", + "http://localhost:8000\n" + ] } ], "source": [ @@ -111,37 +93,29 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/calebcourier/Downloads/demo-050/.venv/lib/python3.12/site-packages/guardrails/validator_base.py:144: UserWarning: Validator with id guardrails/regex_match was not found in the registry! Ignoring...\n", - " warn(f\"Validator with id {name} was not found in the registry! Ignoring...\")\n" - ] - }, { "data": { "text/html": [ "
ValidationOutcome(\n",
-       "    call_id='4593646352',\n",
-       "    raw_llm_output='z-dawg',\n",
-       "    validated_output='z-dawg',\n",
+       "    call_id='5103958320',\n",
+       "    raw_llm_output='Guardrails AI',\n",
+       "    validated_output='Guardrails AI',\n",
        "    reask=None,\n",
-       "    validation_passed=False,\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'4593646352'\u001b[0m,\n", - " \u001b[33mraw_llm_output\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n", - " \u001b[33mvalidated_output\u001b[0m=\u001b[32m'z-dawg'\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;91mFalse\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" ] @@ -162,7 +136,7 @@ "name_case = Guard(name='name-case')\n", "\n", "response = name_case.parse(\n", - " llm_output=\"z-dawg\"\n", + " llm_output=\"Guardrails AI\"\n", ")\n", "\n", "print(response)" @@ -170,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -178,15 +152,15 @@ "text/html": [ "
[\n",
        "    Call(\n",
-       "        id='4593646352',\n",
+       "        id='5103958320',\n",
        "        iterations=[\n",
        "            Iteration(\n",
-       "                id='4588121904',\n",
+       "                id='5107862496',\n",
        "                index=0,\n",
-       "                call_id='4593646352',\n",
+       "                call_id='5103958320',\n",
        "                inputs=Inputs(\n",
        "                    llm_api=None,\n",
-       "                    llm_output='z-dawg',\n",
+       "                    llm_output='Guardrails AI',\n",
        "                    instructions=None,\n",
        "                    prompt=None,\n",
        "                    msg_history=None,\n",
@@ -200,58 +174,32 @@
        "                    llm_response_info=LLMResponse(\n",
        "                        prompt_token_count=None,\n",
        "                        response_token_count=None,\n",
-       "                        output='z-dawg',\n",
+       "                        output='Guardrails AI',\n",
        "                        stream_output=None,\n",
        "                        async_stream_output=None\n",
        "                    ),\n",
        "                    raw_output=None,\n",
-       "                    parsed_output='z-dawg',\n",
-       "                    validation_response='z-dawg',\n",
-       "                    guarded_output='z-dawg',\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=4586558176,\n",
+       "                            instance_id=4636712336,\n",
        "                            property_path='$',\n",
-       "                            value_before_validation='z-dawg',\n",
-       "                            value_after_validation='z-dawg',\n",
-       "                            validation_result=FailResult(\n",
-       "                                outcome='fail',\n",
-       "                                error_message='Result must match ^(?:[A-Z][^\\\\s]*\\\\s?)+$',\n",
-       "                                fix_value='Rb[@1K(ZD}uodO$mh]XmheJWHC2lbc\\rA*L(^Hi6el(h1Gdw;f*4\"$b3e+K;_EDp:Rvh,/!T\n",
-       "C}!u4o\"}-B\\\\6Eh6{9qFpw,t[`:y;gOTt22VvnR;[kX_02kE-#R8iJ.8zJbt>\\\\.FW/>\\'QBTtqyym]Ra4\\'>;\\'imC_zF14Ks`BE@k_NA \n",
-       "Bq*_Q9~Q>hv33+ktfKk|;+k|?GMcF~>z6]j&$7Cb{A},#P.Lw]Al1lU\\':Ig3Q*Ezm8I4\\'|RoR9K-vRf+yN]8`PYO0G=7BWxLDr2kQ4`4lZ!,jW;YY\n",
-       "38eUep*UOV~0@z#$N*3PldH0solD7Q^lu\\\\$RSJ[O*3)B$C{8oK_]U6#Kd}1)pZ?Doqm8J#`QDK*H2:I8ex]g1[,DT\"#:ZpEW_)Jk>C\\'mA{0IJ{B6+\n",
-       "Z>yIDB#HC@%KMMJ?b=`r6X)M\"`eyvUs`&XL{xRW;\\'s4S<Alf9or39ZM~#:YB5HNNw9CxIhA}6``j7=GS7LE1zH8;|7y*^Gal/>8B\\\\l$c|\\\\9~B@&j\n",
-       "a(\\\\yKa#qL)@/#y}O43&iMBC{0E&ta{`R7`>^&*}bA18$tNQGiVPWl[(Blp{3JA$Dv=pPMMGP,<CQ*Z}!HhvLRDzOL@#}Q{Ppj}!/oLD)DZSP!.GcYc\n",
-       ",hT1:Y9$qrr^L7kT9#>rF~O\\x0cRMfxAYpC!L?-~>T`sM?\\'*LB\\x0cHhODokB5Z@Z21kfc4w&}t3}8F|A.3{\\rNgwdgEI7*cY\"ii-Dk8u4ZaG(C/pD\n",
-       "}X!|Cp&hu*/S5}\\\\l@U&:=?1_(HX(um_.x9X+J.i81snKUZnMt_Lb4hsg|@_$wp+D3a,~?0vw\\'JW4O#xrllcY}WlRA?lzEhsoR3kE,d\\'\"X~N`4;hT\n",
-       "0*\\x0bGaXM{8=N+d)[#65\"d]+.9Bg;X_JU[G/1JHA@@|#*Z)3J38f)DmcE:+/\\x0cHL`Eq*5c#G}f`EXDMPd-Mh5%5_:J)j+;n(ql`eTyoz-CR^c<Re\n",
-       "I!l0,EclkG9&jxkUQM\\x0cITy\\\\{:%WKAo-[Z3MAA?TVAPMeS#D2W@W?*olx,IuKyo3zpPc?aQ;-zu]S6AlIiV0jf)G[M2sl)9?yv<I@.j[42B9vaec\n",
-       "^ubuj]M?\\rGhh;ep2bg\\\\|#DUYh)2#I7$x^]:[K>A-FlCii\"fp~5u`?D$Z(a@r9iY<Baiv$`[rm0vk\\\\fejLZd{V&8`Y-\"VJ16E~*b-&W5mq1mXafz6\n",
-       "4vvjYQ#6%R_x?5Jok*~-D\\\\JK9ccn\\'dB\"^;(|[C:UvhG{R?]b<gCTPYlVu2\\\\?B&mTY=.0ER(TaBY{t:]W#L0l~kXJm\"e=>eg=H!_z`8{Wcb7Xg+9t\n",
-       "v@</J\\\\R6\\\\B@N%gr3^~x%9Ee%&\\\\JU<wEsUm`E2\"=Hi1?kLnsmgU^N^=5w415S@=4_;]Cmul\\rVs`^fZo$<mDX^I}N,NK;}^gvMe\\'_joN\\'3g@:^R\n",
-       "kkJY^LU*3~=FjS;6.UCC|\"UQ\\rUolzK;pWH~6>8qv7?M7,.>e}KfvqmKK9\\'ZdhB;*3)<0,R+Jlt3.go3=UK\\'yj\\'Z==[dOwSe]s(shfX({4~4efq~\n",
-       "5j+;_R(t,H-q,-\\x0bN_/*MiPKOlE)ab0wg\\rAYAJ<VC*Ya8Dt02VaI\\\\X0<:4PGmsVVDj5%aHQN:\\\\k>c7JY^l3{+9AA]~J-(i6[>/am{T)*=:9TZ)\n",
-       "hMyg(W4B61Y5\\\\\\\\R_lRT&$C|19TY#{F!8^\\\\N%b)\\'J?EQoH6<yF7HEcRmfSNz!9*k0!$ARAX^<zb8?uvt,2[DyT|w:vx}MF\\'%mKi\\'&Mg^oJKBu}\n",
-       "(v#6vh\\x0cLF<BZ;2:\\rGIzjF=@qr~Y#ls5\"d,$/C6vhIx77+UZ-}B4w.<xMDZiW;\"1f1R~5fI:DzUEJ.INO4u;f$pol{}I\\nQ=X\\\\\"e~w.e9+8xN\"\\\n",
-       "'Tc0Nor:9mfG<2]KrtG5Z$b?>@)@^zeO\">[A@F6/DA/1:)}]z#K7%|GN/|s;0~rPemA({6S\"y({_Hs@9ON>r0cm\\x0cHeL\\'\\'l~>W?DW\".kEdz=Yn1\n",
-       "E5m=IelWe2k-SP\"|=;(|[=WG2qI\\nYdihR~Dr45%Y@K=[k%g%2$c^xPUbxW*lzVHW@G_ymLo1i\\x0cLAKPz@Y;cc\"iSBiCHM0S)/:>M{%?zeP5_8*N_\n",
-       "ijWjS2Pw=$9\";xE2D;>4-*%XP!3\\'Ggc(ERo\\'b*Jt}:uvSDL(/ \n",
-       "O5s+oyIEoBA%WYA^DAc30aj9fsc\\\\gh\\\\B[xKOrT&%|pg\\x0bOW?wUJOngrPag,&7t4%\\'#}?1JA+z]FIu\\'(JDC{kW4)GSsq[yzZ?6\\'=)5Z]E=4=_\n",
-       "W0eIeebu=8\"~uh<kfQab7%a&y$rRb:WLHx48U}dwCp%]MAvGV]>Q\\\\LA%Hh~*T4~\"t!EZ#pNn?:J#s4VVI)fE \n",
-       "A660O)GO$B6*,J\"9+Dd-Yx\\\\P2cTIVe,t%qvs*@h]wMSYG19,Ww6E4aR44Sat1PF${OG@%,.33A-p9G[Q#sRWZf?7Z0!_v]v$+qzkp^rD=.:E#yUg)]\n",
-       "yXw+/bJp@9<kM?+zYV]:1qa|2zeDL*I^zFa\"=KAZzv?.LssH_(,4\\'[8g1O8tL&1ys|>l\\'z]GG%hPk!J!]$*Ez*kR]%n;H\\\\\\'c&~q<lDN73*|gW2X\n",
-       "B:@joK]}j-_GDuE73e8%G=@A,pj&wTMk!I69S3,>,#?^p;:.ADr)$vv\"Ddb9wV_p--,(7/E$()O`jZ\\rWah00;;/9|bou3$*4Uo/y)Tc8]]SK@,$L\\'\n",
-       "OdL!$Q?!~=j\\'kB\\'L42@nj]$V:9XY^[uQwh*F=%z&L,&:@1I',\n",
-       "                                error_spans=None,\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, 25, 14, 19, 56, 81461),\n",
-       "                            end_time=datetime.datetime(2024, 6, 25, 14, 19, 56, 94752)\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",
@@ -281,15 +229,15 @@
       "text/plain": [
        "\u001b[1m[\u001b[0m\n",
        "    \u001b[1;35mCall\u001b[0m\u001b[1m(\u001b[0m\n",
-       "        \u001b[33mid\u001b[0m=\u001b[32m'4593646352'\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'4588121904'\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'4593646352'\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'z-dawg'\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",
@@ -303,58 +251,32 @@
        "                    \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'z-dawg'\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'z-dawg'\u001b[0m,\n",
-       "                    \u001b[33mvalidation_response\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n",
-       "                    \u001b[33mguarded_output\u001b[0m=\u001b[32m'z-dawg'\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;36m4586558176\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'z-dawg'\u001b[0m,\n",
-       "                            \u001b[33mvalue_after_validation\u001b[0m=\u001b[32m'z-dawg'\u001b[0m,\n",
-       "                            \u001b[33mvalidation_result\u001b[0m=\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'Result must match ^\u001b[0m\u001b[32m(\u001b[0m\u001b[32m?:\u001b[0m\u001b[32m[\u001b[0m\u001b[32mA-Z\u001b[0m\u001b[32m]\u001b[0m\u001b[32m[\u001b[0m\u001b[32m^\\\\s\u001b[0m\u001b[32m]\u001b[0m\u001b[32m*\\\\s?\u001b[0m\u001b[32m)\u001b[0m\u001b[32m+$'\u001b[0m,\n",
-       "                                \u001b[33mfix_value\u001b[0m=\u001b[32m'Rb\u001b[0m\u001b[32m[\u001b[0m\u001b[32m@1K\u001b[0m\u001b[32m(\u001b[0m\u001b[32mZD\u001b[0m\u001b[32m}\u001b[0m\u001b[32muodO$mh\u001b[0m\u001b[32m]\u001b[0m\u001b[32mXmheJWHC2lbc\\rA*L\u001b[0m\u001b[32m(\u001b[0m\u001b[32m^Hi6el\u001b[0m\u001b[32m(\u001b[0m\u001b[32mh1Gdw;f*4\"$b3e+K;_EDp:Rvh,/!T\u001b[0m\n",
-       "\u001b[32mC\u001b[0m\u001b[32m}\u001b[0m\u001b[32m!u4o\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m-B\\\\6Eh6\u001b[0m\u001b[32m{\u001b[0m\u001b[32m9qFpw,t\u001b[0m\u001b[32m[\u001b[0m\u001b[32m`:y;gOTt22VvnR;\u001b[0m\u001b[32m[\u001b[0m\u001b[32mkX_02kE-#R8iJ.8zJbt>\\\\.FW/>\\'QBTtqyym\u001b[0m\u001b[32m]\u001b[0m\u001b[32mRa4\\'>;\\'imC_zF14Ks`BE@k_NA \u001b[0m\n",
-       "\u001b[32mBq*_Q9~Q>hv33+ktfKk|;+k|?GMcF~>z6\u001b[0m\u001b[32m]\u001b[0m\u001b[32mj&$7Cb\u001b[0m\u001b[32m{\u001b[0m\u001b[32mA\u001b[0m\u001b[32m}\u001b[0m\u001b[32m,#P.Lw\u001b[0m\u001b[32m]\u001b[0m\u001b[32mAl1lU\\':Ig3Q*Ezm8I4\\'|RoR9K-vRf+yN\u001b[0m\u001b[32m]\u001b[0m\u001b[32m8`\u001b[0m\u001b[32mPYO0G\u001b[0m\u001b[32m=\u001b[0m\u001b[32m7BWxLDr2kQ4\u001b[0m\u001b[32m`4lZ!,jW;YY\u001b[0m\n",
-       "\u001b[32m38eUep*UOV~0@z#$N*3PldH0solD7Q^lu\\\\$RSJ\u001b[0m\u001b[32m[\u001b[0m\u001b[32mO*3\u001b[0m\u001b[32m)\u001b[0m\u001b[32mB$C\u001b[0m\u001b[32m{\u001b[0m\u001b[32m8oK_\u001b[0m\u001b[32m]\u001b[0m\u001b[32mU6#Kd\u001b[0m\u001b[32m}\u001b[0m\u001b[32m1\u001b[0m\u001b[32m)\u001b[0m\u001b[32mpZ?Doqm8J#`QDK*H2:I8ex\u001b[0m\u001b[32m]\u001b[0m\u001b[32mg1\u001b[0m\u001b[32m[\u001b[0m\u001b[32m,DT\"#:ZpEW_\u001b[0m\u001b[32m)\u001b[0m\u001b[32mJk>C\\'mA\u001b[0m\u001b[32m{\u001b[0m\u001b[32m0IJ\u001b[0m\u001b[32m{\u001b[0m\u001b[32mB6+\u001b[0m\n",
-       "\u001b[32mZ>yIDB#HC@%KMMJ?\u001b[0m\u001b[32mb\u001b[0m\u001b[32m=`r6X\u001b[0m\u001b[32m)\u001b[0m\u001b[32mM\"`eyvUs`&XL\u001b[0m\u001b[32m{\u001b[0m\u001b[32mxRW;\\'s4S\u001b[0m\u001b[32m<\u001b[0m\u001b[32mAlf9or39ZM\u001b[0m\u001b[32m~#:YB5HNNw9CxIhA\u001b[0m\u001b[32m}\u001b[0m\u001b[32m6``\u001b[0m\u001b[32mj7\u001b[0m\u001b[32m=\u001b[0m\u001b[32mGS7LE1zH8\u001b[0m\u001b[32m;|7y*^Gal/>8B\\\\l$c|\\\\9~B@&j\u001b[0m\n",
-       "\u001b[32ma\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\\\yKa#qL\u001b[0m\u001b[32m)\u001b[0m\u001b[32m@/#y\u001b[0m\u001b[32m}\u001b[0m\u001b[32mO43&iMBC\u001b[0m\u001b[32m{\u001b[0m\u001b[32m0E&ta\u001b[0m\u001b[32m{\u001b[0m\u001b[32m`R7`>^&*\u001b[0m\u001b[32m}\u001b[0m\u001b[32mbA18$tNQGiVPWl\u001b[0m\u001b[32m[\u001b[0m\u001b[32m(\u001b[0m\u001b[32mBlp\u001b[0m\u001b[32m{\u001b[0m\u001b[32m3JA$\u001b[0m\u001b[32mDv\u001b[0m\u001b[32m=\u001b[0m\u001b[32mpPMMGP\u001b[0m\u001b[32m,rF~O\\x0cRMfxAYpC!L?-~>T`sM?\\'*LB\\x0cHhODokB5Z@Z21kfc4w&\u001b[0m\u001b[32m}\u001b[0m\u001b[32mt3\u001b[0m\u001b[32m}\u001b[0m\u001b[32m8F|A.3\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\rNgwdgEI7*cY\"ii-Dk8u4ZaG\u001b[0m\u001b[32m(\u001b[0m\u001b[32mC/pD\u001b[0m\n",
-       "\u001b[32m}\u001b[0m\u001b[32mX!|Cp&hu*/S5\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\\\l@U&:=?1_\u001b[0m\u001b[32m(\u001b[0m\u001b[32mHX\u001b[0m\u001b[32m(\u001b[0m\u001b[32mum_.x9X+J.i81snKUZnMt_Lb4hsg|@_$wp+D3a,~?0vw\\'JW4O#xrllcY\u001b[0m\u001b[32m}\u001b[0m\u001b[32mWlRA?lzEhsoR3kE,d\\'\"X~N`4;hT\u001b[0m\n",
-       "\u001b[32m0*\\x0bGaXM\u001b[0m\u001b[32m{\u001b[0m\u001b[32m8\u001b[0m\u001b[32m=\u001b[0m\u001b[32mN\u001b[0m\u001b[32m+d\u001b[0m\u001b[32m)\u001b[0m\u001b[32m[\u001b[0m\u001b[32m#65\"d\u001b[0m\u001b[32m]\u001b[0m\u001b[32m+.9Bg;X_JU\u001b[0m\u001b[32m[\u001b[0m\u001b[32mG/1JHA@@|#*Z\u001b[0m\u001b[32m)\u001b[0m\u001b[32m3J38f\u001b[0m\u001b[32m)\u001b[0m\u001b[32mDmcE:+/\\x0cHL`Eq*5c#G\u001b[0m\u001b[32m}\u001b[0m\u001b[32mf`EXDMPd-Mh5%5_:J\u001b[0m\u001b[32m)\u001b[0m\u001b[32mj+;n\u001b[0m\u001b[32m(\u001b[0m\u001b[32mql`eTyoz-CR^cA-FlCii\"fp~5u`?D$Z\u001b[0m\u001b[32m(\u001b[0m\u001b[32ma@r9iY\u001b[0m\u001b[32meg\u001b[0m\u001b[32m=\u001b[0m\u001b[32mH\u001b[0m\u001b[32m!_z`8\u001b[0m\u001b[32m{\u001b[0m\u001b[32mWcb7Xg+9t\u001b[0m\n",
-       "\u001b[32mv@8qv7?M7,.>e\u001b[0m\u001b[32m}\u001b[0m\u001b[32mKfvqmKK9\\'ZdhB;*3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m<0,R+Jlt3.\u001b[0m\u001b[32mgo3\u001b[0m\u001b[32m=\u001b[0m\u001b[32mUK\u001b[0m\u001b[32m\\'yj\\'\u001b[0m\u001b[32mZ\u001b[0m\u001b[32m==\u001b[0m\u001b[32m[\u001b[0m\u001b[32mdOwSe\u001b[0m\u001b[32m]\u001b[0m\u001b[32ms\u001b[0m\u001b[32m(\u001b[0m\u001b[32mshfX\u001b[0m\u001b[32m(\u001b[0m\u001b[32m{\u001b[0m\u001b[32m4~4efq~\u001b[0m\n",
-       "\u001b[32m5j+;_R\u001b[0m\u001b[32m(\u001b[0m\u001b[32mt,H-q,-\\x0bN_/*MiPKOlE\u001b[0m\u001b[32m)\u001b[0m\u001b[32mab0wg\\rAYAJc7JY^l3\u001b[0m\u001b[32m{\u001b[0m\u001b[32m+9AA\u001b[0m\u001b[32m]\u001b[0m\u001b[32m~J-\u001b[0m\u001b[32m(\u001b[0m\u001b[32mi6\u001b[0m\u001b[32m[\u001b[0m\u001b[32m>/am\u001b[0m\u001b[32m{\u001b[0m\u001b[32mT\u001b[0m\u001b[32m)\u001b[0m\u001b[32m*=:9TZ\u001b[0m\u001b[32m)\u001b[0m\n",
-       "\u001b[32mhMyg\u001b[0m\u001b[32m(\u001b[0m\u001b[32mW4B61Y5\\\\\\\\R_lRT&$C|19TY#\u001b[0m\u001b[32m{\u001b[0m\u001b[32mF!8^\\\\N%b\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\'J?EQoH6@\u001b[0m\u001b[32m)\u001b[0m\u001b[32m@^zeO\">\u001b[0m\u001b[32m[\u001b[0m\u001b[32mA@F6/DA/1:\u001b[0m\u001b[32m)\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32mz#K7%|GN/|s;0~rPemA\u001b[0m\u001b[32m(\u001b[0m\u001b[32m{\u001b[0m\u001b[32m6S\"y\u001b[0m\u001b[32m(\u001b[0m\u001b[32m{\u001b[0m\u001b[32m_Hs@9ON>r0cm\\x0cHeL\\'\\'l~>W?DW\".\u001b[0m\u001b[32mkEdz\u001b[0m\u001b[32m=\u001b[0m\u001b[32mYn1\u001b[0m\n",
-       "\u001b[32mE5m\u001b[0m\u001b[32m=IelWe2k-SP\"|=;\u001b[0m\u001b[32m(\u001b[0m\u001b[32m|\u001b[0m\u001b[32m[\u001b[0m\u001b[32m=WG2qI\\nYdihR~Dr45%Y@\u001b[0m\u001b[32mK\u001b[0m\u001b[32m=\u001b[0m\u001b[32m[\u001b[0m\u001b[32mk%g%2$c^xPUbxW*lzVHW@G_ymLo1i\\x0cLAKPz@Y;cc\"iSBiCHM0S\u001b[0m\u001b[32m)\u001b[0m\u001b[32m/:>M\u001b[0m\u001b[32m{\u001b[0m\u001b[32m%?zeP5_8*\u001b[0m\u001b[32mN_\u001b[0m\n",
-       "\u001b[32mijWjS2Pw\u001b[0m\u001b[32m=$9\";xE2D;>4-*%XP!3\\'Ggc\u001b[0m\u001b[32m(\u001b[0m\u001b[32mERo\\'b*Jt\u001b[0m\u001b[32m}\u001b[0m\u001b[32m:uvSDL\u001b[0m\u001b[32m(\u001b[0m\u001b[32m/ \u001b[0m\n",
-       "\u001b[32mO5s+oyIEoBA%WYA^DAc30aj9fsc\\\\gh\\\\B\u001b[0m\u001b[32m[\u001b[0m\u001b[32mxKOrT&%|pg\\x0bOW?wUJOngrPag,&7t4%\\'#\u001b[0m\u001b[32m}\u001b[0m\u001b[32m?1JA+z\u001b[0m\u001b[32m]\u001b[0m\u001b[32mFIu\\'\u001b[0m\u001b[32m(\u001b[0m\u001b[32mJDC\u001b[0m\u001b[32m{\u001b[0m\u001b[32mkW4\u001b[0m\u001b[32m)\u001b[0m\u001b[32mGSsq\u001b[0m\u001b[32m[\u001b[0m\u001b[32myzZ?6\\'=\u001b[0m\u001b[32m)\u001b[0m\u001b[32m5Z\u001b[0m\u001b[32m]\u001b[0m\u001b[32mE\u001b[0m\u001b[32m=\u001b[0m\u001b[32m4\u001b[0m\u001b[32m=\u001b[0m\u001b[32m_\u001b[0m\n",
-       "\u001b[32mW0eIeebu\u001b[0m\u001b[32m=\u001b[0m\u001b[32m8\"\u001b[0m\u001b[32m~uhQ\\\\LA%Hh~*T4~\"t!EZ#pNn?:J#s4VVI\u001b[0m\u001b[32m)\u001b[0m\u001b[32mfE \u001b[0m\n",
-       "\u001b[32mA660O\u001b[0m\u001b[32m)\u001b[0m\u001b[32mGO$B6*,J\"9+Dd-Yx\\\\P2cTIVe,t%qvs*@h\u001b[0m\u001b[32m]\u001b[0m\u001b[32mwMSYG19,Ww6E4aR44Sat1PF$\u001b[0m\u001b[32m{\u001b[0m\u001b[32mOG@%,.33A-p9G\u001b[0m\u001b[32m[\u001b[0m\u001b[32mQ#sRWZf?7Z0!_v\u001b[0m\u001b[32m]\u001b[0m\u001b[32mv$+qzkp^\u001b[0m\u001b[32mrD\u001b[0m\u001b[32m=.:E#yUg\u001b[0m\u001b[32m)\u001b[0m\u001b[32m]\u001b[0m\n",
-       "\u001b[32myXw+/bJp@9l\\'z\u001b[0m\u001b[32m]\u001b[0m\u001b[32mGG%hPk!J!\u001b[0m\u001b[32m]\u001b[0m\u001b[32m$*Ez*kR\u001b[0m\u001b[32m]\u001b[0m\u001b[32m%n;H\\\\\\'c&~q\u001b[0m\u001b[32m,#?^p;:.ADr\u001b[0m\u001b[32m)\u001b[0m\u001b[32m$vv\"Ddb9wV_p--,\u001b[0m\u001b[32m(\u001b[0m\u001b[32m7/E$\u001b[0m\u001b[32m(\u001b[0m\u001b[32m)\u001b[0m\u001b[32mO`jZ\\rWah00;;/9|bou3$*4Uo/y\u001b[0m\u001b[32m)\u001b[0m\u001b[32mTc8\u001b[0m\u001b[32m]\u001b[0m\u001b[32m]\u001b[0m\u001b[32mSK@,$L\\'\u001b[0m\n",
-       "\u001b[32mOdL!$Q?!~=j\\'kB\\'L42@nj\u001b[0m\u001b[32m]\u001b[0m\u001b[32m$V:9XY^\u001b[0m\u001b[32m[\u001b[0m\u001b[32muQwh*\u001b[0m\u001b[32mF\u001b[0m\u001b[32m=%z&L,&:@1I'\u001b[0m,\n",
-       "                                \u001b[33merror_spans\u001b[0m=\u001b[3;35mNone\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;36m25\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m19\u001b[0m, \u001b[1;36m56\u001b[0m, \u001b[1;36m81461\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;36m25\u001b[0m, \u001b[1;36m14\u001b[0m, \u001b[1;36m19\u001b[0m, \u001b[1;36m56\u001b[0m, \u001b[1;36m94752\u001b[0m\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",
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..ad925fb80
--- /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",
+        "add_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",
+        "add_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 b3d28f7ed..46e38cfbf 100644
--- a/docs/pydocs/generate_pydocs.py
+++ b/docs/pydocs/generate_pydocs.py
@@ -1,79 +1,19 @@
-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()",   # noqa
-#             documented_only=True,
-
-#         )
-#     ),
-#     filename="docs/api_reference_markdown/rail.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="# Guard\n\n"
-    + render_loader(
-        PythonLoader(
-            modules=["guardrails.guard"],
-            parser=ParserOptions(print_function=False),
-        ),
-        processor=FilterProcessor(
-            expression="name in ['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' 'add_json_function_calling_tool' 'to_dict' 'from_dict' 'to_runnable']",  # noqa
-            skip_empty_modules=True,
-        ),
-    ),
-    filename="docs/api_reference_markdown/guard.md",
-)
-
-write_to_file(
-    str="# AsyncGuard\n\n"
-    + render_loader(
-        PythonLoader(
-            modules=["guardrails.async_guard"],
-            parser=ParserOptions(print_function=False),
-        ),
-        processor=FilterProcessor(
-            expression="name in ['AsyncGuard', 'guardrails.async_guard', 'guard', '__init__' 'from_rail' 'from_rail_string' 'from_pydantic' 'from_string' 'configure' 'use' 'use_many' '__call__' 'parse' 'validate' 'error_spans_in_output' 'add_json_function_calling_tool' 'to_dict' 'from_dict' 'to_runnable']",  # noqa
-            skip_empty_modules=True,
-        ),
-    ),
-    filename="docs/api_reference_markdown/guard.md",
-)
-
-
-# FIXME: This isn't a thing anymore; validators have been removed.
 write_to_file(
     str="# Validators\n\n"
     + render_loader(
@@ -84,29 +24,6 @@ def write_to_file(str, filename):
     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(
@@ -171,24 +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/guardrails/actions/reask.py b/guardrails/actions/reask.py
index 3ffa8b0ec..5ed0b8d73 100644
--- a/guardrails/actions/reask.py
+++ b/guardrails/actions/reask.py
@@ -17,6 +17,13 @@
 
 ### 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]
 
@@ -60,16 +67,36 @@ def from_dict(cls, obj: Dict[str, Any]) -> Optional["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
 
 
diff --git a/guardrails/async_guard.py b/guardrails/async_guard.py
index fca49a948..911a087d3 100644
--- a/guardrails/async_guard.py
+++ b/guardrails/async_guard.py
@@ -440,7 +440,7 @@ async def __call__(
 
         Args:
             llm_api: The LLM API to call
-                     (e.g. openai.Completion.create or openai.Completion.acreate)
+                     (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.
@@ -496,7 +496,7 @@ async def parse(
             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)
+                     (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
diff --git a/guardrails/call_tracing/__init__.py b/guardrails/call_tracing/__init__.py
index 62078ab46..cfc312cc5 100644
--- a/guardrails/call_tracing/__init__.py
+++ b/guardrails/call_tracing/__init__.py
@@ -1,10 +1,9 @@
-"""
-For tracing (logging) and reporting the timing of Guard and Validator calls.
+"""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.
+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
diff --git a/guardrails/call_tracing/sqlite_trace_handler.py b/guardrails/call_tracing/sqlite_trace_handler.py
index 2831c05d8..1d555d6fd 100644
--- a/guardrails/call_tracing/sqlite_trace_handler.py
+++ b/guardrails/call_tracing/sqlite_trace_handler.py
@@ -1,20 +1,22 @@
-"""
-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.
+"""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
@@ -194,12 +196,14 @@ def log_validator(self, vlog: ValidatorLogs):
     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.
+        """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()
diff --git a/guardrails/call_tracing/trace_entry.py b/guardrails/call_tracing/trace_entry.py
index 259ff3865..6f807a9f1 100644
--- a/guardrails/call_tracing/trace_entry.py
+++ b/guardrails/call_tracing/trace_entry.py
@@ -1,10 +1,10 @@
-"""
-trace_entry.py
+"""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.
+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
diff --git a/guardrails/call_tracing/trace_handler.py b/guardrails/call_tracing/trace_handler.py
index cb383c063..1e689f2d0 100644
--- a/guardrails/call_tracing/trace_handler.py
+++ b/guardrails/call_tracing/trace_handler.py
@@ -1,5 +1,4 @@
-"""
-trace_handler.py
+"""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
@@ -41,9 +40,12 @@
 
 
 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."""
+    """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()
diff --git a/guardrails/call_tracing/tracer_mixin.py b/guardrails/call_tracing/tracer_mixin.py
index dd56307c5..76b1684f3 100644
--- a/guardrails/call_tracing/tracer_mixin.py
+++ b/guardrails/call_tracing/tracer_mixin.py
@@ -1,9 +1,7 @@
-"""
-tracer_mixin.py
+"""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.
+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
diff --git a/guardrails/classes/generic/arbitrary_model.py b/guardrails/classes/generic/arbitrary_model.py
index d26def657..876c978ac 100644
--- a/guardrails/classes/generic/arbitrary_model.py
+++ b/guardrails/classes/generic/arbitrary_model.py
@@ -2,4 +2,6 @@
 
 
 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 99252830f..1f2498900 100644
--- a/guardrails/classes/history/call.py
+++ b/guardrails/classes/history/call.py
@@ -29,6 +29,20 @@
 # We can't inherit from Iteration because python
 # won't let you override a class attribute with a managed attribute
 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."
diff --git a/guardrails/classes/history/call_inputs.py b/guardrails/classes/history/call_inputs.py
index bc99a4905..4aa2363f8 100644
--- a/guardrails/classes/history/call_inputs.py
+++ b/guardrails/classes/history/call_inputs.py
@@ -8,6 +8,21 @@
 
 
 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.",
diff --git a/guardrails/classes/history/inputs.py b/guardrails/classes/history/inputs.py
index f9ee44423..0e6c2ea8f 100644
--- a/guardrails/classes/history/inputs.py
+++ b/guardrails/classes/history/inputs.py
@@ -10,6 +10,29 @@
 
 
 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
     )
diff --git a/guardrails/classes/history/iteration.py b/guardrails/classes/history/iteration.py
index c440c7e95..45c60baab 100644
--- a/guardrails/classes/history/iteration.py
+++ b/guardrails/classes/history/iteration.py
@@ -19,6 +19,18 @@
 
 
 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.
+    """
+
     # I think these should be containered since their names slightly overlap with
     #  outputs, but could be convinced otherwise
     inputs: Inputs = Field(
diff --git a/guardrails/classes/history/outputs.py b/guardrails/classes/history/outputs.py
index dda4c7340..a2c21ac1e 100644
--- a/guardrails/classes/history/outputs.py
+++ b/guardrails/classes/history/outputs.py
@@ -20,6 +20,28 @@
 
 
 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
     )
@@ -47,7 +69,6 @@ class Outputs(IOutputs, ArbitraryModel):
         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
     )
diff --git a/guardrails/classes/llm/llm_response.py b/guardrails/classes/llm/llm_response.py
index 6051d2fca..d26e37a35 100644
--- a/guardrails/classes/llm/llm_response.py
+++ b/guardrails/classes/llm/llm_response.py
@@ -13,6 +13,21 @@ def async_to_sync(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)
 
diff --git a/guardrails/classes/validation/validation_result.py b/guardrails/classes/validation/validation_result.py
index d5732570a..18e6a0baa 100644
--- a/guardrails/classes/validation/validation_result.py
+++ b/guardrails/classes/validation/validation_result.py
@@ -10,11 +10,19 @@
 
 
 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
-
-    # value argument passed to validator.validate
-    # or validator.validate_stream
     validated_chunk: Optional[Any] = None
 
     @classmethod
@@ -45,6 +53,15 @@ def from_dict(cls, obj: Dict[str, Any]) -> "ValidationResult":
 
 
 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:
@@ -76,26 +93,19 @@ def to_dict(self) -> Dict[str, Any]:
         return _dict
 
 
-# FIXME: Add this to json schema
-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.
+class FailResult(ValidationResult, IFailResult):
+    """FailResult is the output type of Validator.validate when validation
+    fails.
 
     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.
+        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.
     """
 
-    start: int
-    end: int
-    # reason validation failed, specific to this chunk
-    reason: str
-
-
-class FailResult(ValidationResult, IFailResult):
     outcome: Literal["fail"] = "fail"
 
     error_message: str
@@ -104,7 +114,7 @@ class FailResult(ValidationResult, IFailResult):
 
     May not exist for non-streamed output.
     """
-    error_spans: Optional[List[ErrorSpan]] = None
+    error_spans: Optional[List["ErrorSpan"]] = None
 
     @classmethod
     def from_interface(cls, i_fail_result: IFailResult) -> "FailResult":
@@ -151,3 +161,21 @@ def to_dict(self) -> Dict[str, Any]:
             ),
         }
         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
index 7cf31f193..cb38e22cb 100644
--- a/guardrails/classes/validation/validator_logs.py
+++ b/guardrails/classes/validation/validator_logs.py
@@ -12,7 +12,20 @@
 
 
 class ValidatorLogs(IValidatorLog, ArbitraryModel):
-    """Logs for a single validator."""
+    """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
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 fe23a1e91..39f26a363 100644
--- a/guardrails/classes/validation_outcome.py
+++ b/guardrails/classes/validation_outcome.py
@@ -16,6 +16,21 @@
 
 
 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
     )
diff --git a/guardrails/errors/__init__.py b/guardrails/errors/__init__.py
index cb6df687f..529467074 100644
--- a/guardrails/errors/__init__.py
+++ b/guardrails/errors/__init__.py
@@ -3,6 +3,8 @@ class ValidationError(Exception):
 
     This is thrown from the validation engine when a Validator has
     on_fail=OnFailActions.EXCEPTION set and validation fails.
+
+    Inherits from Exception.
     """
 
 
diff --git a/guardrails/formatters/json_formatter.py b/guardrails/formatters/json_formatter.py
index 000423851..791b823f1 100644
--- a/guardrails/formatters/json_formatter.py
+++ b/guardrails/formatters/json_formatter.py
@@ -87,6 +87,9 @@ def _jsonschema_to_jsonformer(
 
 
 class JsonFormatter(BaseFormatter):
+    """A formatter that uses Jsonformer to ensure the shape of structured data
+    for Hugging Face models."""
+
     def __init__(self, schema: dict):
         self.output_schema = _jsonschema_to_jsonformer(schema)
 
diff --git a/guardrails/guard.py b/guardrails/guard.py
index 0d071751c..fc8546ec8 100644
--- a/guardrails/guard.py
+++ b/guardrails/guard.py
@@ -80,7 +80,10 @@
     ValidatorMap,
 )
 
-from guardrails.utils.tools_utils import add_json_function_calling_tool
+from guardrails.utils.tools_utils import (
+    # Prevent duplicate declaration in the docs
+    add_json_function_calling_tool as add_json_function_calling_tool_util,
+)
 
 
 class Guard(IGuard, Generic[OT]):
@@ -119,7 +122,11 @@ def __init__(
         validators: Optional[List[ValidatorReference]] = None,
         output_schema: Optional[Dict[str, Any]] = None,
     ):
-        """Initialize the Guard with validators and an output schema."""
+        """Initialize the Guard with serialized validator references and an
+        output schema.
+
+        Output schema must be a valid JSON Schema.
+        """
 
         _try_to_load = name is not None
 
@@ -836,7 +843,7 @@ def __call__(
 
         Args:
             llm_api: The LLM API to call
-                     (e.g. openai.Completion.create or openai.Completion.acreate)
+                     (e.g. openai.completions.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.
@@ -891,7 +898,7 @@ def parse(
             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)
+                     (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
@@ -1218,7 +1225,7 @@ def add_json_function_calling_tool(
     ) -> List[Dict[str, Any]]:
         """Appends an OpenAI tool that specifies the output structure using
         JSON Schema for chat models."""
-        tools = add_json_function_calling_tool(
+        tools = add_json_function_calling_tool_util(
             tools=tools,
             # todo to_dict has a slight bug workaround here
             # but should fix in the long run dont have to
diff --git a/guardrails/llm_providers.py b/guardrails/llm_providers.py
index 9525f075d..19c7cee23 100644
--- a/guardrails/llm_providers.py
+++ b/guardrails/llm_providers.py
@@ -178,7 +178,7 @@ def _invoke_llm(
         Use Guardrails with OpenAI chat engines by doing
         ```
         raw_llm_response, validated_response, *rest = guard(
-            openai.ChatCompletion.create,
+            openai.chat.completions.create,
             prompt_params={...},
             text=...,
             instructions=...,
@@ -754,7 +754,7 @@ async def invoke_llm(
         Use Guardrails with OpenAI chat engines by doing
         ```
         raw_llm_response, validated_response, *rest = guard(
-            openai.ChatCompletion.create,
+            openai.chat.completions.create,
             prompt_params={...},
             text=...,
             instructions=...,
diff --git a/guardrails/prompt/base_prompt.py b/guardrails/prompt/base_prompt.py
index 1eed29cc1..1ff70559e 100644
--- a/guardrails/prompt/base_prompt.py
+++ b/guardrails/prompt/base_prompt.py
@@ -2,7 +2,7 @@
 
 import re
 from string import Template
-from typing import Optional
+from typing import List, Optional
 
 import regex
 
@@ -21,6 +21,7 @@ def __init__(
         *,
         xml_output_schema: Optional[str] = None,
     ):
+        """Initialize and substitute constants in the prompt."""
         self._source = source
         self.format_instructions_start = self.get_format_instructions_idx(source)
 
@@ -55,7 +56,7 @@ def variable_names(self):
     def format_instructions(self):
         return self.source[self.format_instructions_start :]
 
-    def substitute_constants(self, text):
+    def substitute_constants(self, text: str) -> str:
         """Substitute constants in the prompt."""
         # Substitute constants by reading the constants file.
         # Regex to extract all occurrences of ${gr.}
@@ -70,10 +71,10 @@ def substitute_constants(self, text):
 
         return text
 
-    def get_prompt_variables(self):
+    def get_prompt_variables(self) -> List[str]:
         return self.variable_names
 
-    def format(self, **kwargs):
+    def format(self, **kwargs) -> "BasePrompt":
         raise NotImplementedError("Subclasses must implement this method.")
 
     def make_vars_optional(self):
diff --git a/guardrails/prompt/instructions.py b/guardrails/prompt/instructions.py
index 110978a04..6aaf5b078 100644
--- a/guardrails/prompt/instructions.py
+++ b/guardrails/prompt/instructions.py
@@ -25,7 +25,7 @@ def __repr__(self) -> str:
     def __eq__(self, __value: object) -> bool:
         return isinstance(__value, Instructions) and self.source == __value.source
 
-    def format(self, **kwargs):
+    def format(self, **kwargs) -> "Instructions":
         """Format the prompt using the given keyword arguments."""
         # Only use the keyword arguments that are present in the prompt.
         vars = get_template_variables(self.source)
diff --git a/guardrails/prompt/prompt.py b/guardrails/prompt/prompt.py
index cfd335404..8b656162c 100644
--- a/guardrails/prompt/prompt.py
+++ b/guardrails/prompt/prompt.py
@@ -16,7 +16,7 @@ class Prompt(BasePrompt):
     def __eq__(self, __value: object) -> bool:
         return isinstance(__value, Prompt) and self.source == __value.source
 
-    def format(self, **kwargs):
+    def format(self, **kwargs) -> "Prompt":
         """Format the prompt using the given keyword arguments."""
         # Only use the keyword arguments that are present in the prompt.
         vars = get_template_variables(self.source)
diff --git a/guardrails/run/async_stream_runner.py b/guardrails/run/async_stream_runner.py
index cb89f0f9e..a0e8db7bd 100644
--- a/guardrails/run/async_stream_runner.py
+++ b/guardrails/run/async_stream_runner.py
@@ -117,6 +117,7 @@ async def async_step(
         llm_response = await self.async_call(
             instructions, prompt, msg_history, api, output
         )
+        iteration.outputs.llm_response_info = llm_response
         stream_output = llm_response.async_stream_output
         if not stream_output:
             raise ValueError(
@@ -127,6 +128,7 @@ async def async_step(
         fragment = ""
         parsed_fragment, validated_fragment, valid_op = None, None, None
         verified = set()
+        validation_response = ""
 
         if self.output_type == OutputTypes.STRING:
             async for chunk in stream_output:
@@ -159,6 +161,7 @@ async def async_step(
                         "Reasks are not yet supported with streaming. Please "
                         "remove reasks from schema or disable streaming."
                     )
+                validation_response += cast(str, validated_fragment)
                 passed = call_log.status == pass_status
                 yield ValidationOutcome(
                     call_id=call_log.id,  # type: ignore
@@ -196,6 +199,10 @@ async def async_step(
                         "remove reasks from schema or disable streaming."
                     )
 
+                if self.output_type == OutputTypes.LIST:
+                    validation_response = cast(list, validated_fragment)
+                else:
+                    validation_response = cast(dict, validated_fragment)
                 yield ValidationOutcome(
                     call_id=call_log.id,  # type: ignore
                     raw_llm_output=fragment,
@@ -205,10 +212,8 @@ async def async_step(
 
         iteration.outputs.raw_output = fragment
         # FIXME: Handle case where parsing continuously fails/is a reask
-        iteration.outputs.parsed_output = parsed_fragment  # type: ignore
-        iteration.outputs.validation_response = (
-            cast(str, validated_fragment) if validated_fragment else None
-        )
+        iteration.outputs.parsed_output = parsed_fragment or fragment  # type: ignore
+        iteration.outputs.validation_response = validation_response
         iteration.outputs.guarded_output = valid_op
 
     def get_chunk_text(self, chunk: Any, api: Union[PromptCallableBase, None]) -> str:
diff --git a/guardrails/run/stream_runner.py b/guardrails/run/stream_runner.py
index a968548e3..e8c87a6c9 100644
--- a/guardrails/run/stream_runner.py
+++ b/guardrails/run/stream_runner.py
@@ -126,6 +126,8 @@ def step(
         # Call: run the API that returns a generator wrapped in LLMResponse
         llm_response = self.call(instructions, prompt, msg_history, api, output)
 
+        iteration.outputs.llm_response_info = llm_response
+
         # Get the stream (generator) from the LLMResponse
         stream = llm_response.stream_output
         if stream is None:
@@ -137,6 +139,7 @@ def step(
         fragment = ""
         parsed_fragment, validated_fragment, valid_op = None, None, None
         verified = set()
+        validation_response = ""
         # Loop over the stream
         # and construct "fragments" of concatenated chunks
         # for now, handle string and json schema differently
@@ -184,6 +187,7 @@ def step(
                         "remove reasks from schema or disable streaming."
                     )
                 # 5. Convert validated fragment to a pretty JSON string
+                validation_response += cast(str, validated_text)
                 passed = call_log.status == pass_status
                 yield ValidationOutcome(
                     call_id=call_log.id,  # type: ignore
@@ -258,6 +262,10 @@ def step(
                         "remove reasks from schema or disable streaming."
                     )
 
+                if self.output_type == OutputTypes.LIST:
+                    validation_response = cast(list, validated_fragment)
+                else:
+                    validation_response = cast(dict, validated_fragment)
                 # 5. Convert validated fragment to a pretty JSON string
                 yield ValidationOutcome(
                     call_id=call_log.id,  # type: ignore
@@ -270,8 +278,8 @@ def step(
         iteration.outputs.raw_output = fragment
         # Do we need to care about the type here?
         # What happens if parsing continuously fails?
-        iteration.outputs.parsed_output = parsed_fragment  # type: ignore
-        iteration.outputs.validation_response = validated_fragment
+        iteration.outputs.parsed_output = parsed_fragment or fragment  # type: ignore
+        iteration.outputs.validation_response = validation_response
         iteration.outputs.guarded_output = valid_op
 
     def is_last_chunk(self, chunk: Any, api: Union[PromptCallableBase, None]) -> bool:
diff --git a/guardrails/types/__init__.py b/guardrails/types/__init__.py
index 03b033ce4..632f2781f 100644
--- a/guardrails/types/__init__.py
+++ b/guardrails/types/__init__.py
@@ -17,13 +17,13 @@
 )
 
 __all__ = [
-    "MessageHistory",
     "OnFailAction",
+    "RailTypes",
     "PrimitiveTypes",
+    "MessageHistory",
     "ModelOrListOfModels",
     "ModelOrListOrDict",
     "ModelOrModelUnion",
-    "RailTypes",
     "PydanticValidatorTuple",
     "PydanticValidatorSpec",
     "UseValidatorSpec",
diff --git a/guardrails/types/inputs.py b/guardrails/types/inputs.py
index deb8d7ab5..07c738d12 100644
--- a/guardrails/types/inputs.py
+++ b/guardrails/types/inputs.py
@@ -2,5 +2,5 @@
 
 from guardrails.prompt.prompt import Prompt
 
-
+"""List[Dict[str, Union[Prompt, str]]]"""
 MessageHistory = List[Dict[str, Union[Prompt, str]]]
diff --git a/guardrails/types/on_fail.py b/guardrails/types/on_fail.py
index 83946aec6..7e9bfa3b9 100644
--- a/guardrails/types/on_fail.py
+++ b/guardrails/types/on_fail.py
@@ -4,6 +4,23 @@
 
 
 class OnFailAction(str, Enum):
+    """OnFailAction is an Enum that represents the different actions that can
+    be taken when a validation fails.
+
+    Attributes:
+        REASK (Literal["reask"]): On failure, Reask the LLM.
+        FIX (Literal["fix"]): On failure, apply a static fix.
+        FILTER (Literal["filter"]): On failure, filter out the invalid values.
+        REFRAIN (Literal["refrain"]): On failure, refrain from responding;
+            return an empty value.
+        NOOP (Literal["noop"]): On failure, do nothing.
+        EXCEPTION (Literal["exception"]): On failure, raise a ValidationError.
+        FIX_REASK (Literal["fix_reask"]): On failure, apply a static fix,
+            check if the fixed value passed validation, if not then reask the LLM.
+        CUSTOM (Literal["custom"]): On failure, call a custom function with the
+            invalid value and the FailResult's from any validators run on the value.
+    """
+
     REASK = "reask"
     FIX = "fix"
     FILTER = "filter"
diff --git a/guardrails/types/rail.py b/guardrails/types/rail.py
index 912447862..474efad8b 100644
--- a/guardrails/types/rail.py
+++ b/guardrails/types/rail.py
@@ -3,6 +3,25 @@
 
 
 class RailTypes(str, Enum):
+    """RailTypes is an Enum that represents the builtin tags for RAIL xml.
+
+    Attributes:
+        STRING (Literal["string"]): A string value.
+        INTEGER (Literal["integer"]): An integer value.
+        FLOAT (Literal["float"]): A float value.
+        BOOL (Literal["bool"]): A boolean value.
+        DATE (Literal["date"]): A date value.
+        TIME (Literal["time"]): A time value.
+        DATETIME (Literal["date-time: - A datetime value.
+        PERCENTAGE (Literal["percentage"]): A percentage value represented as a string.
+            Example "20.5%".
+        ENUM (Literal["enum"]): An enum value.
+        LIST (Literal["list"]): A list/array value.
+        OBJECT (Literal["object"]): An object/dictionary value.
+        CHOICE (Literal["choice"]): The options for a discrimated union.
+        CASE (Literal["case"]): A dictionary that contains a discrimated union.
+    """
+
     STRING = "string"
     INTEGER = "integer"
     FLOAT = "float"
diff --git a/guardrails/validators/__init__.py b/guardrails/validators/__init__.py
index 394991271..5054a31f3 100644
--- a/guardrails/validators/__init__.py
+++ b/guardrails/validators/__init__.py
@@ -12,4 +12,5 @@
     "ValidationResult",
     "PassResult",
     "FailResult",
+    "ErrorSpan",
 ]
diff --git a/package.json b/package.json
index 093c72081..47f21975e 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,8 @@
     "clear": "docusaurus clear",
     "serve": "docusaurus serve",
     "write-translations": "docusaurus write-translations",
-    "write-heading-ids": "docusaurus write-heading-ids"
+    "write-heading-ids": "docusaurus write-heading-ids",
+    "restart": "rm -rf docs/api_reference_markdown; rm -rf docs-build; npm run start"
   },
   "dependencies": {
     "@docusaurus/core": "^3.1.1",
diff --git a/tests/unit_tests/test_guard_log.py b/tests/unit_tests/test_guard_log.py
index fc332f374..9799c7b36 100644
--- a/tests/unit_tests/test_guard_log.py
+++ b/tests/unit_tests/test_guard_log.py
@@ -23,7 +23,8 @@
 
 
 def test_multiprocessing_hoisted():
-    """Preallocate a shared trace handler and try to log from multiple subprocesses."""
+    """Preallocate a shared trace handler and try to log from multiple
+    subprocesses."""
     with Pool(NUM_THREADS) as pool:
         pool.map(_hoisted_logger, ["multiproc_hoist" + msg for msg in STOCK_MESSAGES])
 

From a59f26b200495099fe54761024f34d86037a0063 Mon Sep 17 00:00:00 2001
From: zsimjee 
Date: Fri, 5 Jul 2024 11:58:27 -0700
Subject: [PATCH 5/5] update litellm defaults nb to use messages

---
 docs/examples/lite_llm_defaults.ipynb | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/docs/examples/lite_llm_defaults.ipynb b/docs/examples/lite_llm_defaults.ipynb
index a29073b21..06ec7641f 100644
--- a/docs/examples/lite_llm_defaults.ipynb
+++ b/docs/examples/lite_llm_defaults.ipynb
@@ -61,6 +61,13 @@
     "    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)"