-
Notifications
You must be signed in to change notification settings - Fork 207
LangChain/LangGraph span input.value / output.value as JSON (not repr) #2827
Copy link
Copy link
Open
Labels
Description
Summary
Span attributes input.value and output.value were being set to the string representation (Python repr/str) of LangChain message objects instead of JSON. Downstream UIs (e.g. Arize) and replay tooling expect parseable JSON.
Root cause
- Where:
openinference-instrumentation-langchainin_tracer.py:_update_spanuses_as_input(_convert_io(run.inputs))and_as_output(_convert_io(run.outputs))._convert_iouses_json_dumps()for the payload. - Why:
_json_dumps()uses_OpenInferenceJSONEncoder. The encoder handled Pydantic (model_dump) and dataclasses but did not explicitly handle LangChainBaseMessage. When encoding failed (e.g. Run state like{"messages": [HumanMessage(...)]}), the code fell back tosafe_json_dumps(obj), which usesjson.dumps(..., default=str), so message objects becamestr(message)(repr-like:content='...' additional_kwargs={} ...).
Fix (Suggested)
- In
_OpenInferenceJSONEncoder.default():- Before other branches: if
isinstance(obj, BaseMessage), serialize to a JSON-serializable dict using (in order)message_to_dict(obj),model_dump(),model_dump_json()+json.loads, Pydantic v1dict(), orto_json().
- Before other branches: if
- Optional import:
from langchain_core.messages.base import message_to_dictwithImportErrorfallback for older langchain_core. - New test:
test_convert_io_langchain_messages_json_not_repr(state{"messages": [HumanMessage(...)]}→json.loads(value)and content assertion).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
In Review