@votadev/tooncode 2.2.9 → 2.3.1
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 -60
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@votadev/tooncode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
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.1"
|
|
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
|
|
|
@@ -5359,51 +5385,6 @@ def main(_initial_prompt=None):
|
|
|
5359
5385
|
console.print()
|
|
5360
5386
|
tool_results = execute_tools(content)
|
|
5361
5387
|
|
|
5362
|
-
# -- Stuck detection: if same error repeats, auto-call bosshelp --
|
|
5363
|
-
for tr in tool_results:
|
|
5364
|
-
tr_content = tr.get("content", "")
|
|
5365
|
-
if isinstance(tr_content, str) and ("[error" in tr_content or "exit code" in tr_content):
|
|
5366
|
-
_last_errors.append(tr_content[:200])
|
|
5367
|
-
# If 3+ errors in recent tools, we're stuck
|
|
5368
|
-
if len(_last_errors) >= 3:
|
|
5369
|
-
recent = _last_errors[-3:]
|
|
5370
|
-
# Check if errors are similar (stuck in loop)
|
|
5371
|
-
if len(set(recent)) <= 2:
|
|
5372
|
-
console.print("\n[bold magenta][auto-bosshelp] Stuck detected! Asking Claude Code for help...[/bold magenta]")
|
|
5373
|
-
# Gather context
|
|
5374
|
-
recent_text = "\n".join(
|
|
5375
|
-
block.get("text", "")
|
|
5376
|
-
for msg in messages[-4:]
|
|
5377
|
-
if msg.get("role") == "assistant"
|
|
5378
|
-
for block in (msg.get("content") if isinstance(msg.get("content"), list) else [])
|
|
5379
|
-
if block.get("type") == "text"
|
|
5380
|
-
)
|
|
5381
|
-
boss_answer = _boss_help(
|
|
5382
|
-
problem=f"I keep getting the same error and can't fix it",
|
|
5383
|
-
context=recent_text[:1000],
|
|
5384
|
-
error="\n".join(recent),
|
|
5385
|
-
)
|
|
5386
|
-
_last_errors.clear()
|
|
5387
|
-
_post_bosshelp = True
|
|
5388
|
-
# MUST append tool_results first (API requires it after tool_use)
|
|
5389
|
-
messages.append({"role": "user", "content": tool_results})
|
|
5390
|
-
# Then add bosshelp as assistant+user pair
|
|
5391
|
-
fix_instructions = f"[BOSSHELP]\n{boss_answer}\n\n"
|
|
5392
|
-
fix_instructions += "APPLY THIS FIX NOW:\n"
|
|
5393
|
-
fix_instructions += "1. Read each file mentioned\n"
|
|
5394
|
-
fix_instructions += "2. Use edit tool to apply changes\n"
|
|
5395
|
-
fix_instructions += "3. Run commands if needed\n"
|
|
5396
|
-
fix_instructions += "4. Verify the fix works\n"
|
|
5397
|
-
fix_instructions += "USE TOOLS. Do NOT explain."
|
|
5398
|
-
messages.append({"role": "assistant", "content": [{"type": "text", "text": "Let me apply the fix."}]})
|
|
5399
|
-
messages.append({"role": "user", "content": [{"type": "text", "text":
|
|
5400
|
-
fix_instructions,
|
|
5401
|
-
"cache_control": {"type": "ephemeral"}}]})
|
|
5402
|
-
continue
|
|
5403
|
-
else:
|
|
5404
|
-
# Successful tool = reset error tracking
|
|
5405
|
-
_last_errors.clear()
|
|
5406
|
-
|
|
5407
5388
|
messages.append({"role": "user", "content": tool_results})
|
|
5408
5389
|
continue # Always continue after tool use
|
|
5409
5390
|
|