diff --git a/components/claw_modules/claw_core/src/claw_core_events.c b/components/claw_modules/claw_core/src/claw_core_events.c index 274aa0ab4..803186e45 100644 --- a/components/claw_modules/claw_core/src/claw_core_events.c +++ b/components/claw_modules/claw_core/src/claw_core_events.c @@ -302,9 +302,11 @@ void claw_core_publish_stage_tool_calls(const claw_core_request_t *request, const char *name = response->tool_calls[i].name ? response->tool_calls[i].name : "?"; const char *args = response->tool_calls[i].arguments_json; if (args && args[0]) { - written = snprintf(buf + off, sizeof(buf) - off, "%s%s(%.40s%s)", - i == 0 ? "" : ", ", name, args, - strlen(args) > 40 ? "..." : ""); + size_t arg_len = strlen(args); + size_t prefix_len = utf8_prefix_len(args, 40); + written = snprintf(buf + off, sizeof(buf) - off, "%s%s(%.*s%s)", + i == 0 ? "" : ", ", name, (int)prefix_len, args, + arg_len > prefix_len ? "..." : ""); } else { written = snprintf(buf + off, sizeof(buf) - off, "%s%s", i == 0 ? "" : ", ", name); diff --git a/components/claw_modules/claw_manager/src/claw_agent_mgr.c b/components/claw_modules/claw_manager/src/claw_agent_mgr.c index da3f9158d..3e40a4586 100644 --- a/components/claw_modules/claw_manager/src/claw_agent_mgr.c +++ b/components/claw_modules/claw_manager/src/claw_agent_mgr.c @@ -643,9 +643,13 @@ static void claw_agent_mgr_completion_observer(const claw_core_completion_summar if ((size_t)written >= sizeof(text)) { size_t suffix_len = strlen(truncated_suffix); if (suffix_len + 1U < sizeof(text)) { - strlcpy(text + sizeof(text) - suffix_len - 1U, - truncated_suffix, - suffix_len + 1U); + size_t p = sizeof(text) - suffix_len - 1U; + /* Back off so the suffix never splices into the middle of a + * multi-byte UTF-8 sequence, which would emit invalid bytes. */ + while (p > 0 && ((unsigned char)text[p] & 0xC0) == 0x80) { + p--; + } + strlcpy(text + p, truncated_suffix, sizeof(text) - p); } }