Skip to content

Commit 496a8cb

Browse files
chore(langchain-ibm): Update chat_models to support granite with Langchain (#150)
* chore(langchain-ibm): Update chat_models to support granite with Langchain * fix integration tests * fix integration tests v2 * make format * patch version * remove indent * fixed normalize_tool_arguments function
1 parent b3f92ad commit 496a8cb

File tree

6 files changed

+43
-6
lines changed

6 files changed

+43
-6
lines changed

libs/ibm/langchain_ibm/chat_models.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""IBM watsonx.ai chat wrapper."""
22

3+
import ast
34
import hashlib
45
import json
56
import logging
@@ -90,6 +91,35 @@
9091
logger = logging.getLogger(__name__)
9192

9293

94+
def normalize_tool_arguments(args_str: str) -> str:
95+
"""Ensure arguments is always a proper JSON string.
96+
97+
Handles:
98+
- JSON string
99+
- Python dict string
100+
- Extra wrapping quotes like '"{...}"'
101+
Args:
102+
args_str: tool call args_str.
103+
104+
Returns:
105+
The LangChain tool call arguments args_str.
106+
"""
107+
# Try to parse as JSON
108+
try:
109+
parsed = json.loads(args_str)
110+
except json.JSONDecodeError:
111+
pass
112+
else:
113+
if isinstance(parsed, str):
114+
json.loads(parsed)
115+
return parsed
116+
return args_str
117+
118+
# Try Python literal (e.g., "{'a': 1}")
119+
obj: Any = ast.literal_eval(args_str)
120+
return json.dumps(obj, ensure_ascii=False)
121+
122+
93123
def _convert_dict_to_message(_dict: Mapping[str, Any], call_id: str) -> BaseMessage:
94124
"""Convert a dictionary to a LangChain message.
95125
@@ -117,6 +147,13 @@ def _convert_dict_to_message(_dict: Mapping[str, Any], call_id: str) -> BaseMess
117147
if raw_tool_calls := _dict.get("tool_calls"):
118148
additional_kwargs["tool_calls"] = raw_tool_calls
119149
for raw_tool_call in raw_tool_calls:
150+
## Code change to support langgraph with A2A and graph.astream.
151+
if "function" in raw_tool_call:
152+
func = raw_tool_call.get("function", {})
153+
if "arguments" in func:
154+
raw_args = raw_tool_call["function"]["arguments"]
155+
json_args_str = normalize_tool_arguments(raw_args)
156+
raw_tool_call["function"]["arguments"] = json_args_str
120157
try:
121158
tool_calls.append(parse_tool_call(raw_tool_call, return_id=True))
122159
except Exception as e:

libs/ibm/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "pdm.backend"
44

55
[project]
66
name = "langchain-ibm"
7-
version = "0.3.19.dev1"
7+
version = "0.3.20"
88
description = "An integration package connecting IBM watsonx.ai and LangChain"
99
authors = [{ name = "IBM" }]
1010
license = { text = "MIT" }

libs/ibm/tests/integration_tests/test_embeddings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
WX_PROJECT_ID = os.environ.get("WATSONX_PROJECT_ID", "")
1616

1717
URL = "https://us-south.ml.cloud.ibm.com"
18-
MODEL_ID = "ibm/slate-125m-english-rtrvr"
18+
MODEL_ID = "ibm/slate-125m-english-rtrvr-v2"
1919

2020
DOCUMENTS = ["What is a generative ai?", "What is a loan and how does it works?"]
2121

libs/ibm/tests/integration_tests/test_embeddings_standard.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
URL = "https://us-south.ml.cloud.ibm.com"
1111

12-
MODEL_ID = "ibm/granite-embedding-107m-multilingual"
12+
MODEL_ID = "ibm/granite-embedding-278m-multilingual"
1313

1414

1515
class TestWatsonxEmbeddingsStandard(EmbeddingsIntegrationTests):

libs/ibm/tests/integration_tests/test_rerank.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
URL = "https://us-south.ml.cloud.ibm.com"
1616

17-
MODEL_ID = "ibm/slate-125m-english-rtrvr"
17+
MODEL_ID = "ibm/slate-125m-english-rtrvr-v2"
1818

1919

2020
def test_01_rerank_init() -> None:
@@ -47,7 +47,7 @@ def test_02_rerank_documents() -> None:
4747

4848

4949
def test_02_rerank_documents_with_params() -> None:
50-
params = RerankParameters(truncate_input_tokens=1)
50+
params = RerankParameters(truncate_input_tokens=2)
5151
test_documents = [
5252
Document(page_content="This is a test document."),
5353
]

libs/ibm/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)