fixes
This commit is contained in:
@@ -638,12 +638,16 @@ async def _execute_single_tool_call_async(
|
|||||||
out = "USER REJECTED: tool execution cancelled" if _res is None else await mcp_client.async_dispatch(name, args)
|
out = "USER REJECTED: tool execution cancelled" if _res is None else await mcp_client.async_dispatch(name, args)
|
||||||
else:
|
else:
|
||||||
out = await mcp_client.async_dispatch(name, args)
|
out = await mcp_client.async_dispatch(name, args)
|
||||||
|
if tool_log_callback:
|
||||||
|
tool_log_callback(f"# MCP TOOL: {name}\n{json.dumps(args, indent=1)}", out)
|
||||||
elif name == TOOL_NAME:
|
elif name == TOOL_NAME:
|
||||||
scr = cast(str, args.get("script", ""))
|
scr = cast(str, args.get("script", ""))
|
||||||
_append_comms("OUT", "tool_call", {"name": TOOL_NAME, "id": call_id, "script": scr})
|
_append_comms("OUT", "tool_call", {"name": TOOL_NAME, "id": call_id, "script": scr})
|
||||||
out = await asyncio.to_thread(_run_script, scr, base_dir, qa_callback, patch_callback)
|
out = await asyncio.to_thread(_run_script, scr, base_dir, qa_callback, patch_callback)
|
||||||
else:
|
else:
|
||||||
out = f"ERROR: unknown tool '{name}'"
|
out = f"ERROR: unknown tool '{name}'"
|
||||||
|
if tool_log_callback:
|
||||||
|
tool_log_callback(f"ERROR: {name}", out)
|
||||||
|
|
||||||
return (name, call_id, out, name)
|
return (name, call_id, out, name)
|
||||||
|
|
||||||
@@ -1495,6 +1499,26 @@ def _ensure_minimax_client() -> None:
|
|||||||
raise ValueError("MiniMax API key not found in credentials.toml")
|
raise ValueError("MiniMax API key not found in credentials.toml")
|
||||||
_minimax_client = OpenAI(api_key=api_key, base_url="https://api.minimax.chat/v1")
|
_minimax_client = OpenAI(api_key=api_key, base_url="https://api.minimax.chat/v1")
|
||||||
|
|
||||||
|
def _repair_deepseek_history(history: list[dict[str, Any]]) -> None:
|
||||||
|
if not history:
|
||||||
|
return
|
||||||
|
last = history[-1]
|
||||||
|
if last.get("role") != "assistant":
|
||||||
|
return
|
||||||
|
tool_calls = last.get("tool_calls", [])
|
||||||
|
if not tool_calls:
|
||||||
|
return
|
||||||
|
call_ids = [tc.get("id") for tc in tool_calls if tc.get("id")]
|
||||||
|
for cid in call_ids:
|
||||||
|
# Check if already present in tail (to be safe, though usually missing if we're here)
|
||||||
|
already_has = any(m.get("role") == "tool" and m.get("tool_call_id") == cid for m in history[-len(call_ids)-1:])
|
||||||
|
if not already_has:
|
||||||
|
history.append({
|
||||||
|
"role": "tool",
|
||||||
|
"tool_call_id": cid,
|
||||||
|
"content": "ERROR: Session was interrupted before tool result was recorded.",
|
||||||
|
})
|
||||||
|
|
||||||
def _send_deepseek(md_content: str, user_message: str, base_dir: str,
|
def _send_deepseek(md_content: str, user_message: str, base_dir: str,
|
||||||
file_items: list[dict[str, Any]] | None = None,
|
file_items: list[dict[str, Any]] | None = None,
|
||||||
discussion_history: str = "",
|
discussion_history: str = "",
|
||||||
@@ -1522,6 +1546,7 @@ def _send_deepseek(md_content: str, user_message: str, base_dir: str,
|
|||||||
|
|
||||||
# Update history following Anthropic pattern
|
# Update history following Anthropic pattern
|
||||||
with _deepseek_history_lock:
|
with _deepseek_history_lock:
|
||||||
|
_repair_deepseek_history(_deepseek_history)
|
||||||
if discussion_history and not _deepseek_history:
|
if discussion_history and not _deepseek_history:
|
||||||
user_content = f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"
|
user_content = f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ class AppController:
|
|||||||
"output_tokens": 0,
|
"output_tokens": 0,
|
||||||
"cache_read_input_tokens": 0,
|
"cache_read_input_tokens": 0,
|
||||||
"cache_creation_input_tokens": 0,
|
"cache_creation_input_tokens": 0,
|
||||||
|
"total_tokens": 0,
|
||||||
"last_latency": 0.0
|
"last_latency": 0.0
|
||||||
}
|
}
|
||||||
self.mma_tier_usage: Dict[str, Dict[str, Any]] = {
|
self.mma_tier_usage: Dict[str, Dict[str, Any]] = {
|
||||||
@@ -673,6 +674,21 @@ class AppController:
|
|||||||
with self._disc_entries_lock:
|
with self._disc_entries_lock:
|
||||||
self.disc_entries.append(item)
|
self.disc_entries.append(item)
|
||||||
|
|
||||||
|
def _process_pending_tool_calls(self) -> bool:
|
||||||
|
"""Drains pending tool calls into the tool log. Returns True if any were processed."""
|
||||||
|
with self._pending_tool_calls_lock:
|
||||||
|
items = self._pending_tool_calls[:]
|
||||||
|
self._pending_tool_calls.clear()
|
||||||
|
if not items:
|
||||||
|
return False
|
||||||
|
for item in items:
|
||||||
|
self._append_tool_log(
|
||||||
|
item.get("script", ""),
|
||||||
|
item.get("result", ""),
|
||||||
|
source_tier=item.get("source_tier")
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
def _test_callback_func_write_to_file(self, data: str) -> None:
|
def _test_callback_func_write_to_file(self, data: str) -> None:
|
||||||
"""A dummy function that a custom_callback would execute for testing."""
|
"""A dummy function that a custom_callback would execute for testing."""
|
||||||
callback_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tests", "artifacts", "temp_callback_output.txt")
|
callback_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tests", "artifacts", "temp_callback_output.txt")
|
||||||
@@ -996,15 +1012,7 @@ class AppController:
|
|||||||
def _handle_request_event(self, event: events.UserRequestEvent) -> None:
|
def _handle_request_event(self, event: events.UserRequestEvent) -> None:
|
||||||
"""Processes a UserRequestEvent by calling the AI client."""
|
"""Processes a UserRequestEvent by calling the AI client."""
|
||||||
ai_client.set_current_tier(None) # Ensure main discussion is untagged
|
ai_client.set_current_tier(None) # Ensure main discussion is untagged
|
||||||
if self.ui_auto_add_history:
|
# Clear response area for new turn
|
||||||
with self._pending_history_adds_lock:
|
|
||||||
self._pending_history_adds.append({
|
|
||||||
"role": "User",
|
|
||||||
"content": event.prompt,
|
|
||||||
"collapsed": True,
|
|
||||||
"ts": project_manager.now_ts()
|
|
||||||
})
|
|
||||||
# Clear response area for new turn
|
|
||||||
self.ai_response = ""
|
self.ai_response = ""
|
||||||
csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()])
|
csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()])
|
||||||
ai_client.set_custom_system_prompt("\n\n".join(csp))
|
ai_client.set_custom_system_prompt("\n\n".join(csp))
|
||||||
@@ -1063,6 +1071,16 @@ class AppController:
|
|||||||
"model": model
|
"model": model
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if kind == "request":
|
||||||
|
if self.ui_auto_add_history:
|
||||||
|
with self._pending_history_adds_lock:
|
||||||
|
self._pending_history_adds.append({
|
||||||
|
"role": "User",
|
||||||
|
"content": payload.get("message", ""),
|
||||||
|
"collapsed": payload.get("collapsed", False),
|
||||||
|
"ts": entry.get("ts", project_manager.now_ts())
|
||||||
|
})
|
||||||
|
|
||||||
if kind in ("tool_result", "tool_call"):
|
if kind in ("tool_result", "tool_call"):
|
||||||
role = "Tool" if kind == "tool_result" else "Vendor API"
|
role = "Tool" if kind == "tool_result" else "Vendor API"
|
||||||
content = ""
|
content = ""
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ class App:
|
|||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
self._process_pending_gui_tasks()
|
self._process_pending_gui_tasks()
|
||||||
self._process_pending_history_adds()
|
self._process_pending_history_adds()
|
||||||
|
self.controller._process_pending_tool_calls()
|
||||||
self._render_track_proposal_modal()
|
self._render_track_proposal_modal()
|
||||||
self._render_patch_modal()
|
self._render_patch_modal()
|
||||||
# Auto-save (every 60s)
|
# Auto-save (every 60s)
|
||||||
|
|||||||
Reference in New Issue
Block a user