Skip to content

fix(predict-rlm): serialize Pydantic values at JSON boundaries - #60

Draft
taogaetz wants to merge 1 commit into
Trampoline-AI:mainfrom
taogaetz:agent/serialize-pydantic-json-boundaries
Draft

fix(predict-rlm): serialize Pydantic values at JSON boundaries#60
taogaetz wants to merge 1 commit into
Trampoline-AI:mainfrom
taogaetz:agent/serialize-pydantic-json-boundaries

Conversation

@taogaetz

Copy link
Copy Markdown

Rationale

PredictRLM could fail after otherwise successful typed agent work when Pydantic outputs contained JSON-native domain types such as date and Decimal. The same values could also make a subsequent JSPI-backed agent step unusable when a typed result was passed forward as input. This breaks chained typed workflows even though the values have valid Pydantic JSON representations.

Two focused reproductions exposed the violated behavior:

  1. Strict terminal evidence rejected a valid Pydantic output with TypeError: Object of type date is not JSON serializable.
  2. JSPI variable injection rendered Python-mode values such as datetime.date(...) into the pre-execution state, causing sandbox iterations to fail before user code could run.

The root cause was Python-mode Pydantic dumping at both JSON/transport boundaries. Nested rich scalars survived normalization and were later handed to JSON serialization or embedded into generated Python source.

Summary

  • Dump Pydantic v2 values in JSON mode in the shared plain-data normalizer.
  • Route JSPI variable normalization through that shared recursive normalizer instead of its Python-mode model dump.
  • Add terminal-evidence coverage for nested date and Decimal values.
  • Add JSPI execution coverage proving those values arrive as plain data and execute successfully.

Test Plan

  • uv run pytest -o addopts= tests/test_interpreter.py::TestNoneValueSerialization::test_pydantic_model_with_date_and_decimal_injected_as_plain_data tests/test_interpreter.py::TestNoneValueSerialization::test_pydantic_model_with_none_fields_injected_as_variable tests/test_small_kernel.py::test_strict_evidence_serializes_pydantic_dates_and_decimals -q
  • uv run ruff check src/predict_rlm/serialization.py src/predict_rlm/backends/jspi/backend.py tests/test_small_kernel.py tests/test_interpreter.py
  • Re-ran the downstream chained Avalanche workflow through extraction, validation, typed audit input, terminal evidence, and final result; all nodes completed successfully.


from dspy.primitives.code_interpreter import CodeInterpreterError, FinalOutput
from dspy.primitives.python_interpreter import PythonInterpreter
from pydantic import BaseModel

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

????

@taogaetz

Copy link
Copy Markdown
Author

One concern before this moves out of draft: although the code diff is small, changing the shared Pydantic normalizer from mode="python" to mode="json" is a broad semantic change. It affects every Pydantic value passing through this shared boundary, not only date and Decimal or the JSPI path.

We should confirm that converting rich Python values to JSON-native forms at this layer is the intended contract, and consider narrowing the change or adding broader compatibility coverage if it is not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant