feat(middleware): add structured output handling for OpenAI models in EvoMemoryMiddleware

This commit is contained in:
X-iZhang
2026-03-03 01:14:12 +00:00
parent a574492123
commit 32bbd1a1af
+18 -2
View File
@@ -564,6 +564,20 @@ class EvoMemoryMiddleware(AgentMiddleware):
conversation="\n".join(conv_parts),
)
@staticmethod
def _structured_output_kwargs(model: BaseChatModel) -> dict[str, Any]:
"""Return extra kwargs for with_structured_output based on provider.
OpenAI's Structured Outputs (default since langchain-openai 0.3)
requires ``additionalProperties: false`` and all-required fields.
The ExtractedMemory schema uses Optional unions which violate these
rules. Fall back to function_calling for OpenAI models.
"""
model_module = type(model).__module__ or ""
if model_module.startswith("langchain_openai"):
return {"method": "function_calling"}
return {}
@staticmethod
def _disable_thinking(model: BaseChatModel) -> BaseChatModel:
"""Return a copy of the model with thinking/reasoning disabled.
@@ -601,7 +615,8 @@ class EvoMemoryMiddleware(AgentMiddleware):
prompt = self._build_extraction_prompt(memory, messages)
try:
plain_model = self._disable_thinking(model)
structured_model = plain_model.with_structured_output(ExtractedMemory)
so_kwargs = self._structured_output_kwargs(plain_model)
structured_model = plain_model.with_structured_output(ExtractedMemory, **so_kwargs)
result = structured_model.invoke(prompt)
return result.model_dump(exclude_none=True)
except Exception as e: # noqa: BLE001
@@ -613,7 +628,8 @@ class EvoMemoryMiddleware(AgentMiddleware):
prompt = self._build_extraction_prompt(memory, messages)
try:
plain_model = self._disable_thinking(model)
structured_model = plain_model.with_structured_output(ExtractedMemory)
so_kwargs = self._structured_output_kwargs(plain_model)
structured_model = plain_model.with_structured_output(ExtractedMemory, **so_kwargs)
result = await structured_model.ainvoke(prompt)
return result.model_dump(exclude_none=True)
except Exception as e: # noqa: BLE001