@ -3,12 +3,14 @@ from __future__ import annotations
import json
import re
from json import JSONDecodeError
from typing import Any , Callable , List , Optional
from typing import Any , Callable , List , Optional , Type
import jsonpatch # type: ignore[import]
from langchain_core . exceptions import OutputParserException
from langchain_core . output_parsers . format_instructions import JSON_FORMAT_INSTRUCTIONS
from langchain_core . output_parsers . transform import BaseCumulativeTransformOutputParser
from langchain_core . pydantic_v1 import BaseModel
def _replace_new_line ( match : re . Match [ str ] ) - > str :
@ -170,7 +172,7 @@ def parse_and_check_json_markdown(text: str, expected_keys: List[str]) -> dict:
return json_obj
class Simple JsonOutputParser( BaseCumulativeTransformOutputParser [ Any ] ) :
class JsonOutputParser( BaseCumulativeTransformOutputParser [ Any ] ) :
""" Parse the output of an LLM call to a JSON object.
When used in streaming mode , it will yield partial JSON objects containing
@ -180,6 +182,8 @@ class SimpleJsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
describing the difference between the previous and the current object .
"""
pydantic_object : Optional [ Type [ BaseModel ] ] = None
def _diff ( self , prev : Optional [ Any ] , next : Any ) - > Any :
return jsonpatch . make_patch ( prev , next ) . patch
@ -190,6 +194,26 @@ class SimpleJsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
except JSONDecodeError as e :
raise OutputParserException ( f " Invalid json output: { text } " ) from e
def get_format_instructions ( self ) - > str :
if self . pydantic_object is None :
return " Return a JSON object. "
else :
schema = self . pydantic_object . schema ( )
# Remove extraneous fields.
reduced_schema = schema
if " title " in reduced_schema :
del reduced_schema [ " title " ]
if " type " in reduced_schema :
del reduced_schema [ " type " ]
# Ensure json in context is well-formed with double quotes.
schema_str = json . dumps ( reduced_schema )
return JSON_FORMAT_INSTRUCTIONS . format ( schema = schema_str )
@property
def _type ( self ) - > str :
return " simple_json_output_parser "
# For backwards compatibility
SimpleJsonOutputParser = JsonOutputParser