Skip to content

Commit 7567b4d

Browse files
Merge pull request #191 from EvanProgramming/codex/issue-190-parse-deepseek-dsml
fix: parse DeepSeek DSML tool calls
2 parents 6f8b381 + 105eabb commit 7567b4d

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

‎main.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def _terminal_supports_unicode() -> bool:
6666
else: _SPINNER_FRAMES = ["/", "-", "\\", "|"]; _BAR_FILL = "#"; _BAR_EMPTY = "."; _CHECK = "+"; _CIRCLE = "o"; _HALF = ">"; _BOX_TL = "+"; _BOX_H = "-"; _BOX_BL = "+"; _BOX_V = "|"; _DOT = "."; _NBHYPHEN = "-"
6767

6868
import ast
69+
import html
6970
import json
7071
import os
7172
import queue
@@ -3658,6 +3659,26 @@ def _add(data: dict) -> None:
36583659
and len(obj) <= 3): # action, args + optionally one more key
36593660
_add(obj)
36603661

3662+
marker = r"(?:||DSML||||DSML||\|\|DSML\|\||\|DSML\|)"
3663+
invoke_pattern = re.compile(
3664+
rf"<{marker}\s*invoke\s+name=[\"'](?P<name>[^\"']+)[\"'][^>]*>"
3665+
rf"(?P<body>[\s\S]*?)</{marker}\s*invoke\s*>",
3666+
re.IGNORECASE,
3667+
)
3668+
parameter_pattern = re.compile(
3669+
rf"<{marker}\s*parameter\s+name=[\"'](?P<name>[^\"']+)[\"'][^>]*>"
3670+
rf"(?P<value>[\s\S]*?)</{marker}\s*parameter\s*>",
3671+
re.IGNORECASE,
3672+
)
3673+
for invoke in invoke_pattern.finditer(text):
3674+
parameters = list(parameter_pattern.finditer(invoke.group("body")))
3675+
raw_action = invoke.group("name").strip().lower()
3676+
if (len(parameters) == 1 and parameters[0].group("name").strip().lower() == "args"
3677+
and _is_valid_action(raw_action)):
3678+
args = html.unescape(parameters[0].group("value").strip())
3679+
if args:
3680+
_add({"action": TOOL_ALIASES.get(raw_action, raw_action), "args": args})
3681+
36613682
for data in _collect_unwrapped_tool_calls(text)[0]:
36623683
if _is_valid_action(data.get("action")):
36633684
_add(data)

‎tests/test_task_consistency.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,23 @@ def test_unwrapped_provider_aliases_are_bounded_and_canonicalized(self):
735735
main._collect_tool_calls("run_cmd:\n```bash\nprintf newline-fence\n```")[-1],
736736
{"action": "run_cmd", "args": "printf newline-fence"},
737737
)
738+
dsml = (
739+
'<||DSML|| calls><||DSML|| invoke name="execute_terminal_command">'
740+
'<||DSML|| parameter name="args" string="true">'
741+
'curl http://127.0.0.1:8765/?a=1&amp;b=2'
742+
'</||DSML|| parameter></||DSML|| invoke></||DSML|| calls>'
743+
)
744+
self.assertEqual(
745+
main._collect_tool_calls(dsml),
746+
[{"action": "execute_terminal_command", "args": "curl http://127.0.0.1:8765/?a=1&b=2"}],
747+
)
748+
self.assertEqual(main._collect_tool_calls(dsml.replace("||DSML||", "|DSML|")), [
749+
{"action": "execute_terminal_command", "args": "curl http://127.0.0.1:8765/?a=1&b=2"},
750+
])
751+
self.assertEqual(main._collect_tool_calls(dsml.replace(
752+
'</||DSML|| parameter>',
753+
'</||DSML|| parameter><||DSML|| parameter name="path">x</||DSML|| parameter>',
754+
)), [])
738755

739756
malformed = main._parse_model_response("run_cmd: ```bash\nprintf alias-ok")
740757
self.assertEqual(malformed["tool_calls"], [])

0 commit comments

Comments
 (0)