Skip to content

Commit 9259640

Browse files
committed
fix(core): sanitize interrupted tool call arguments
1 parent 60f3909 commit 9259640

8 files changed

Lines changed: 3155 additions & 2877 deletions

File tree

agentscope-core/src/main/java/io/agentscope/core/agent/accumulator/ToolCallsAccumulator.java

Lines changed: 286 additions & 293 deletions
Large diffs are not rendered by default.

agentscope-core/src/main/java/io/agentscope/core/formatter/dashscope/DashScopeToolsHelper.java

Lines changed: 325 additions & 335 deletions
Large diffs are not rendered by default.

agentscope-core/src/main/java/io/agentscope/core/formatter/openai/OpenAIMessageConverter.java

Lines changed: 481 additions & 471 deletions
Large diffs are not rendered by default.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2024-2026 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.agentscope.core.util;
17+
18+
import java.util.Collections;
19+
import java.util.Map;
20+
21+
/** Utility helpers for normalizing tool-call arguments stored as JSON strings. */
22+
public final class ToolCallJsonUtils {
23+
24+
private ToolCallJsonUtils() {}
25+
26+
/**
27+
* Parse a raw JSON object string into a map.
28+
*
29+
* @param rawJson raw JSON object string
30+
* @return parsed map, or empty map when the payload is blank or invalid
31+
*/
32+
public static Map<String, Object> parseJsonObjectOrEmpty(String rawJson) {
33+
if (rawJson == null || rawJson.isBlank()) {
34+
return Collections.emptyMap();
35+
}
36+
37+
try {
38+
@SuppressWarnings("unchecked")
39+
Map<String, Object> parsed = JsonUtils.getJsonCodec().fromJson(rawJson, Map.class);
40+
return parsed != null ? parsed : Collections.emptyMap();
41+
} catch (Exception ignored) {
42+
return Collections.emptyMap();
43+
}
44+
}
45+
46+
/**
47+
* Return a provider-safe JSON object string for tool call arguments.
48+
*
49+
* <p>Valid raw JSON is preserved as-is. Invalid or partial JSON falls back to serializing the
50+
* structured input map, and ultimately to an empty JSON object.
51+
*
52+
* @param rawJson raw tool-call content accumulated from streaming chunks
53+
* @param input structured tool-call input map
54+
* @return safe JSON object string for downstream provider formatters
55+
*/
56+
public static String sanitizeArgumentsJson(String rawJson, Map<String, Object> input) {
57+
if (isValidJsonObject(rawJson)) {
58+
return rawJson;
59+
}
60+
return serializeInputOrEmpty(input);
61+
}
62+
63+
/**
64+
* Check whether a raw tool-call payload is a valid JSON object.
65+
*
66+
* @param rawJson raw tool-call content
67+
* @return true when the payload parses as a JSON object
68+
*/
69+
public static boolean isValidJsonObject(String rawJson) {
70+
return !parseJsonObjectOrEmpty(rawJson).isEmpty()
71+
|| (rawJson != null && "{}".equals(rawJson.trim()));
72+
}
73+
74+
private static String serializeInputOrEmpty(Map<String, Object> input) {
75+
if (input == null || input.isEmpty()) {
76+
return "{}";
77+
}
78+
79+
try {
80+
return JsonUtils.getJsonCodec().toJson(input);
81+
} catch (Exception ignored) {
82+
return "{}";
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)