Files
mlflow--mlflow/tests/langgraph/test_langgraph_model_export.py
2026-07-13 13:22:34 +08:00

78 lines
3.1 KiB
Python

import json
import mlflow
from mlflow.types.schema import Object, ParamSchema, ParamSpec, Property
def test_langgraph_save_as_code():
input_example = {"messages": [{"role": "user", "content": "what is the weather in sf?"}]}
with mlflow.start_run():
model_info = mlflow.langchain.log_model(
"tests/langgraph/sample_code/langgraph_prebuilt.py",
name="langgraph",
input_example=input_example,
)
# (role, content)
expected_messages = [
("human", "what is the weather in sf?"),
("agent", ""), # tool message does not have content
("tools", "It's always sunny in sf"),
("agent", "The weather in San Francisco is always sunny!"),
]
loaded_graph = mlflow.langchain.load_model(model_info.model_uri)
response = loaded_graph.invoke(input_example)
messages = response["messages"]
assert len(messages) == 4
for msg, (role, expected_content) in zip(messages, expected_messages):
assert msg.content == expected_content
# Need to reload to reset the iterator in FakeOpenAI
loaded_graph = mlflow.langchain.load_model(model_info.model_uri)
response = loaded_graph.stream(input_example)
# .stream() response does not includes the first Human message
for chunk, (role, expected_content) in zip(response, expected_messages[1:]):
assert chunk[role]["messages"][0].content == expected_content
loaded_pyfunc = mlflow.pyfunc.load_model(model_info.model_uri)
response = loaded_pyfunc.predict(input_example)[0]
messages = response["messages"]
assert len(messages) == 4
for msg, (role, expected_content) in zip(messages, expected_messages):
assert msg["content"] == expected_content
# response should be json serializable
assert json.dumps(response) is not None
loaded_pyfunc = mlflow.pyfunc.load_model(model_info.model_uri)
response = loaded_pyfunc.predict_stream(input_example)
for chunk, (role, expected_content) in zip(response, expected_messages[1:]):
assert chunk[role]["messages"][0]["content"] == expected_content
def test_langgraph_model_invoke_with_dictionary_params(monkeypatch):
input_example = {"messages": [{"role": "user", "content": "What's the weather in nyc?"}]}
params = {"config": {"configurable": {"thread_id": "1"}}}
monkeypatch.setenv("MLFLOW_CONVERT_MESSAGES_DICT_FOR_LANGCHAIN", "false")
with mlflow.start_run():
model_info = mlflow.langchain.log_model(
"tests/langgraph/sample_code/langgraph_prebuilt.py",
name="model",
input_example=(input_example, params),
)
assert model_info.signature.params == ParamSchema([
ParamSpec(
"config",
Object([Property("configurable", Object([Property("thread_id", "string")]))]),
params["config"],
)
])
langchain_model = mlflow.langchain.load_model(model_info.model_uri)
result = langchain_model.invoke(input_example, **params)
pyfunc_model = mlflow.pyfunc.load_model(model_info.model_uri)
assert len(pyfunc_model.predict(input_example, params)[0]["messages"]) == len(
result["messages"]
)