@votadev/tooncode 2.2.9 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tooncode.py +41 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@votadev/tooncode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "🇹🇭 Thai Coding Agent CLI — Claude Code alternative powered by free models. 20 tools, multi-agent team, browser automation, MCP servers.",
|
|
5
5
|
"author": "VotaLab",
|
|
6
6
|
"license": "MIT",
|
package/tooncode.py
CHANGED
|
@@ -8,7 +8,7 @@ Usage:
|
|
|
8
8
|
python tooncode.py
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
VERSION = "2.
|
|
11
|
+
VERSION = "2.3.0"
|
|
12
12
|
|
|
13
13
|
import httpx
|
|
14
14
|
import json
|
|
@@ -2917,27 +2917,53 @@ def _get_current_api_url() -> str:
|
|
|
2917
2917
|
|
|
2918
2918
|
def _validate_messages(messages: list):
|
|
2919
2919
|
"""Fix message ordering issues before sending to API."""
|
|
2920
|
-
#
|
|
2921
|
-
#
|
|
2920
|
+
# Rules:
|
|
2921
|
+
# 1. Must alternate user/assistant
|
|
2922
|
+
# 2. tool_result (in user msg) must come right after assistant with tool_use
|
|
2923
|
+
# 3. First message must be user
|
|
2922
2924
|
fixed = []
|
|
2923
|
-
for
|
|
2925
|
+
for msg in messages:
|
|
2924
2926
|
role = msg.get("role", "")
|
|
2925
|
-
# Skip empty messages
|
|
2926
2927
|
content = msg.get("content", [])
|
|
2927
2928
|
if not content:
|
|
2928
2929
|
continue
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2930
|
+
|
|
2931
|
+
# Detect message types
|
|
2932
|
+
is_tool_result = isinstance(content, list) and any(
|
|
2933
|
+
isinstance(b, dict) and b.get("type") == "tool_result" for b in content)
|
|
2934
|
+
has_tool_use = isinstance(content, list) and any(
|
|
2935
|
+
isinstance(b, dict) and b.get("type") == "tool_use" for b in content)
|
|
2936
|
+
|
|
2937
|
+
if not fixed:
|
|
2938
|
+
# First message must be user
|
|
2939
|
+
if role != "user":
|
|
2940
|
+
fixed.append({"role": "user", "content": [{"type": "text", "text": "(start)"}]})
|
|
2941
|
+
fixed.append(msg)
|
|
2942
|
+
continue
|
|
2943
|
+
|
|
2944
|
+
prev = fixed[-1]
|
|
2945
|
+
prev_role = prev.get("role", "")
|
|
2946
|
+
prev_content = prev.get("content", [])
|
|
2947
|
+
prev_has_tool_use = isinstance(prev_content, list) and any(
|
|
2948
|
+
isinstance(b, dict) and b.get("type") == "tool_use" for b in prev_content)
|
|
2949
|
+
|
|
2950
|
+
# tool_result must follow assistant with tool_use
|
|
2951
|
+
if is_tool_result and role == "user":
|
|
2952
|
+
if prev_role != "assistant" or not prev_has_tool_use:
|
|
2953
|
+
# Remove this tool_result — it's orphaned
|
|
2954
|
+
continue
|
|
2955
|
+
fixed.append(msg)
|
|
2956
|
+
continue
|
|
2957
|
+
|
|
2958
|
+
# Fix consecutive same role
|
|
2959
|
+
if role == prev_role:
|
|
2960
|
+
if role == "user":
|
|
2961
|
+
fixed.append({"role": "assistant", "content": [{"type": "text", "text": "(continuing)"}]})
|
|
2962
|
+
else:
|
|
2939
2963
|
fixed.append({"role": "user", "content": [{"type": "text", "text": "(continue)"}]})
|
|
2964
|
+
|
|
2940
2965
|
fixed.append(msg)
|
|
2966
|
+
|
|
2941
2967
|
messages.clear()
|
|
2942
2968
|
messages.extend(fixed)
|
|
2943
2969
|
|