This is an automated email from the ASF dual-hosted git repository.
wenjin272 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-agents.git
The following commit(s) were added to refs/heads/main by this push:
new b29d654c [integration][python] Pass DashScope tool call ids through to
Tongyi tool results (#1168)
b29d654c is described below
commit b29d654c77433fc970b1c8469febd78f5f98947e
Author: Edson <[email protected]>
AuthorDate: Tue Sep 29 02:10:07 2026 -0400
[integration][python] Pass DashScope tool call ids through to Tongyi tool
results (#1168)
Generated-by: Claude Code 2.1.259 (Claude Opus 5.5)
---
.../chat_models/tests/test_tongyi_chat_model.py | 52 ++++++++++++++++++++++
.../integrations/chat_models/tongyi_chat_model.py | 30 ++++++++-----
2 files changed, 72 insertions(+), 10 deletions(-)
diff --git
a/python/flink_agents/integrations/chat_models/tests/test_tongyi_chat_model.py
b/python/flink_agents/integrations/chat_models/tests/test_tongyi_chat_model.py
index 4e47eed4..aef71f5a 100644
---
a/python/flink_agents/integrations/chat_models/tests/test_tongyi_chat_model.py
+++
b/python/flink_agents/integrations/chat_models/tests/test_tongyi_chat_model.py
@@ -189,3 +189,55 @@ def test_default_model_when_omitted() -> None:
"""Verify per-integration default applies when `model` is omitted from
__init__."""
setup = TongyiChatModelSetup(connection="conn")
assert setup.model == DEFAULT_MODEL
+
+
+def test_tool_call_ids_round_trip(monkeypatch: pytest.MonkeyPatch) -> None:
+ """The DashScope call id reaches both the assistant call and the tool
result."""
+ tool_call_response = SimpleNamespace(
+ status_code=200,
+ output={
+ "choices": [
+ {
+ "message": {
+ "role": "assistant",
+ "content": "",
+ "tool_calls": [
+ {
+ "id": "call_abc",
+ "type": "function",
+ "function": {
+ "name": "add",
+ "arguments": '{"a": 1, "b": 2}',
+ },
+ }
+ ],
+ }
+ }
+ ]
+ },
+ usage=SimpleNamespace(input_tokens=10, output_tokens=5),
+ )
+ mock_call = MagicMock(return_value=tool_call_response)
+ monkeypatch.setattr(
+
"flink_agents.integrations.chat_models.tongyi_chat_model.Generation.call",
+ mock_call,
+ )
+ connection = TongyiChatModelConnection(api_key="fake-key")
+
+ response = connection.chat(
+ [ChatMessage.of(MessageRole.USER, "What is 1 + 2?")], model=test_model
+ )
+ # The tool call action reads this key into the tool result's external_id.
+ assert response.tool_calls[0]["original_id"] == "call_abc"
+
+ tool_result = ChatMessage.of(
+ MessageRole.TOOL, "3", extra_args={"external_id": "call_abc"}
+ )
+ connection.chat(
+ [ChatMessage.of(MessageRole.USER, "What is 1 + 2?"), response,
tool_result],
+ model=test_model,
+ )
+
+ sent = mock_call.call_args.kwargs["messages"]
+ assert sent[1]["tool_calls"][0]["id"] == "call_abc"
+ assert sent[2] == {"role": "tool", "content": "3", "tool_call_id":
"call_abc"}
diff --git a/python/flink_agents/integrations/chat_models/tongyi_chat_model.py
b/python/flink_agents/integrations/chat_models/tongyi_chat_model.py
index 425d91fb..bc72760d 100644
--- a/python/flink_agents/integrations/chat_models/tongyi_chat_model.py
+++ b/python/flink_agents/integrations/chat_models/tongyi_chat_model.py
@@ -310,6 +310,9 @@ class TongyiChatModelConnection(BaseChatModelConnection):
args = json.loads(args)
tool_call_dict = {
"id": uuid.uuid4(),
+ # The provider's id, under the key the tool call action reads
to
+ # pass it back as the tool result's external_id.
+ "original_id": tc.get("id"),
"type": "function",
"function": {
"name": fn.get("name"),
@@ -347,9 +350,7 @@ class TongyiChatModelConnection(BaseChatModelConnection):
if message.role == MessageRole.ASSISTANT:
msg_dict["tool_calls"] = [
{
- "id": tc.get("additional_kwargs", {}).get(
- "original_tool_call_id", str(tc.get("id", ""))
- ),
+ "id": _provider_tool_call_id(tc),
"type": "function",
"function": {
"name": tc["function"]["name"],
@@ -359,19 +360,28 @@ class TongyiChatModelConnection(BaseChatModelConnection):
for tc in message.tool_calls
]
elif message.role == MessageRole.TOOL:
- tool_call_info = message.tool_calls[0]
- original_id = tool_call_info.get("additional_kwargs",
{}).get(
- "original_tool_call_id"
+ msg_dict["tool_call_id"] = _provider_tool_call_id(
+ message.tool_calls[0]
)
- if original_id:
- msg_dict["tool_call_id"] = original_id
- elif "id" in tool_call_info:
- msg_dict["tool_call_id"] = str(tool_call_info["id"])
+
+ if message.role == MessageRole.TOOL and message.extra_args.get(
+ "external_id"
+ ):
+ # The tool call action records the provider's call id here.
+ msg_dict["tool_call_id"] =
str(message.extra_args["external_id"])
tongyi_messages.append(msg_dict)
return cast("List[Dict[str, Any]]", tongyi_messages)
+def _provider_tool_call_id(tool_call: Dict[str, Any]) -> str:
+ """Return the DashScope id of a tool call, falling back to the framework
id."""
+ original_id = tool_call.get("original_id") or tool_call.get(
+ "additional_kwargs", {}
+ ).get("original_tool_call_id")
+ return str(original_id) if original_id else str(tool_call.get("id", ""))
+
+
class TongyiChatModelSetup(BaseChatModelSetup):
"""Tongyi chat model setup which manages chat configuration and will
internally
call Tongyi chat model connection to do chat.