Skip to content

fix(messages): preserve non-string tool-call args in Hermes ShareGPT round-trip - #4170

Merged
fengju0213 merged 2 commits into
camel-ai:masterfrom
ebarkhordar:fix/hermes-sharegpt-json-roundtrip
Jul 14, 2026
Merged

fix(messages): preserve non-string tool-call args in Hermes ShareGPT round-trip#4170
fengju0213 merged 2 commits into
camel-ai:masterfrom
ebarkhordar:fix/hermes-sharegpt-json-roundtrip

Conversation

@ebarkhordar

Copy link
Copy Markdown
Contributor

Related Issue

Closes #4169

Description

HermesFunctionFormatter serialized tool calls by interpolating the dict into an f-string (Python repr) and parsed them back with json.loads(text.replace("'", '"')). That blanket quote swap corrupts any argument string containing an apostrophe (repr wraps such a value in double quotes, so the inner ' becomes a stray "), and True/False/None are not valid JSON. json.loads raised, the tool call was dropped, and from_sharegpt silently degraded the message to a plain BaseMessage with args lost. All-string args round-trip fine, which is why the existing test missed it.

Invariant: to_sharegpt() -> from_sharegpt() preserves func_name and args for any JSON-representable arguments.

Fix (single file):

  • format_tool_call / format_tool_response emit json.dumps(..., ensure_ascii=False) instead of interpolating the dict.
  • extract_tool_calls / extract_tool_response parse with json.loads, falling back to ast.literal_eval for legacy single-quoted (Python-repr) payloads so previously serialized data keeps round-tripping.

No dependency changes (ast and json are stdlib).

What is the purpose of this pull request?

  • Bug fix

Verification

Verified in a clean python:3.12-slim container. The two new tests (test_hermes_sharegpt_roundtrip_preserves_non_string_args, test_hermes_extract_tool_calls_parses_legacy_repr_payload) fail on master and pass on this branch; the existing Hermes/ShareGPT tests stay green.

On master (source unchanged, new tests added):

Warning: Failed to parse tool call: Expecting ',' delimiter: line 1 column 49 (char 48)
FAILED test_hermes_sharegpt_roundtrip_preserves_non_string_args - assert isinstance(BaseMessage(...), FunctionCallingMessage)
FAILED test_hermes_extract_tool_calls_parses_legacy_repr_payload - assert 0 == 1
2 failed, 9 deselected

On this branch:

....                                                                     [100%]
4 passed, 7 deselected in 1.83s

The one unrelated failure in test/messages/test_func_message.py (test_roleplay_conversion_with_tools) is a missing OPENAI_API_KEY in the sandbox, not affected by this change.

Checklist

…round-trip

HermesFunctionFormatter serialized tool calls with Python repr
(f"{tool_call_dict}") and parsed them back with
json.loads(text.replace("'", '"')). That blanket quote swap corrupts any
argument string containing an apostrophe (repr wraps such a value in double
quotes, so the inner ' becomes a stray ") and True/False/None are not valid
JSON, so json.loads raised, the tool call was dropped, and from_sharegpt
silently degraded the message to a plain BaseMessage with args lost. All-string
args round-trip fine, which is why the existing test missed this.

Emit tool calls and responses as JSON (json.dumps) and parse them as JSON,
falling back to ast.literal_eval for legacy single-quoted payloads so older
serialized data keeps round-tripping. Add regression tests for args with
apostrophes, booleans, None and floats, plus the legacy repr parse path.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 40a27854-3dcb-42af-9af6-66f70ffd4ea7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@fengju0213

Copy link
Copy Markdown
Collaborator

thanks @ebarkhordar for opening the issue and pr! lgtm

@fengju0213
fengju0213 merged commit a8a9309 into camel-ai:master Jul 14, 2026
8 of 13 checks passed
@ebarkhordar

Copy link
Copy Markdown
Contributor Author

Thanks for the quick turnaround on both the issue and the PR. Glad the JSON round-trip fix was useful; I'll keep an eye on the ShareGPT conversion path.

@ebarkhordar
ebarkhordar deleted the fix/hermes-sharegpt-json-roundtrip branch July 15, 2026 21:37
@fengju0213 fengju0213 added this to the Sprint 56 milestone Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hermes ShareGPT round-trip drops tool-call args with apostrophes, booleans or None

2 participants