mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-24 15:43:54 +00:00
[core] add test for json parser (#15297)
this should fail, but isnt --------- Co-authored-by: Nuno Campos <nuno@langchain.dev>
This commit is contained in:
parent
ec090745a6
commit
c3b3b77a11
@ -10,6 +10,7 @@ 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.outputs import Generation
|
||||
from langchain_core.pydantic_v1 import BaseModel
|
||||
|
||||
|
||||
@ -106,11 +107,7 @@ def parse_partial_json(s: str, *, strict: bool = False) -> Any:
|
||||
new_s += closing_char
|
||||
|
||||
# Attempt to parse the modified string as JSON.
|
||||
try:
|
||||
return json.loads(new_s, strict=strict)
|
||||
except json.JSONDecodeError:
|
||||
# If we still can't parse the string as JSON, return None to indicate failure.
|
||||
return None
|
||||
return json.loads(new_s, strict=strict)
|
||||
|
||||
|
||||
def parse_json_markdown(
|
||||
@ -187,12 +184,22 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
|
||||
def _diff(self, prev: Optional[Any], next: Any) -> Any:
|
||||
return jsonpatch.make_patch(prev, next).patch
|
||||
|
||||
def parse(self, text: str) -> Any:
|
||||
def parse_result(self, result: List[Generation], *, partial: bool = False) -> Any:
|
||||
text = result[0].text
|
||||
text = text.strip()
|
||||
try:
|
||||
return parse_json_markdown(text.strip())
|
||||
except JSONDecodeError as e:
|
||||
raise OutputParserException(f"Invalid json output: {text}") from e
|
||||
if partial:
|
||||
try:
|
||||
return parse_json_markdown(text)
|
||||
except JSONDecodeError:
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return parse_json_markdown(text)
|
||||
except JSONDecodeError as e:
|
||||
raise OutputParserException(f"Invalid json output: {text}") from e
|
||||
|
||||
def parse(self, text: str) -> Any:
|
||||
return self.parse_result([Generation(text=text)])
|
||||
|
||||
def get_format_instructions(self) -> str:
|
||||
if self.pydantic_object is None:
|
||||
|
@ -487,3 +487,9 @@ async def test_partial_text_json_output_parser_diff_async() -> None:
|
||||
chain = input_iter | SimpleJsonOutputParser(diff=True)
|
||||
|
||||
assert [p async for p in chain.astream(None)] == EXPECTED_STREAMED_JSON_DIFF
|
||||
|
||||
|
||||
def test_raises_error() -> None:
|
||||
parser = SimpleJsonOutputParser()
|
||||
with pytest.raises(Exception):
|
||||
parser.invoke("hi")
|
||||
|
@ -78,17 +78,20 @@ class JsonOutputFunctionsParser(BaseCumulativeTransformOutputParser[Any]):
|
||||
raise OutputParserException(f"Could not parse function call: {exc}")
|
||||
try:
|
||||
if partial:
|
||||
if self.args_only:
|
||||
return parse_partial_json(
|
||||
function_call["arguments"], strict=self.strict
|
||||
)
|
||||
else:
|
||||
return {
|
||||
**function_call,
|
||||
"arguments": parse_partial_json(
|
||||
try:
|
||||
if self.args_only:
|
||||
return parse_partial_json(
|
||||
function_call["arguments"], strict=self.strict
|
||||
),
|
||||
}
|
||||
)
|
||||
else:
|
||||
return {
|
||||
**function_call,
|
||||
"arguments": parse_partial_json(
|
||||
function_call["arguments"], strict=self.strict
|
||||
),
|
||||
}
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
else:
|
||||
if self.args_only:
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user