tunacode-cli 0.0.76.1__py3-none-any.whl → 0.0.76.2__py3-none-any.whl

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.

Potentially problematic release.


This version of tunacode-cli might be problematic. Click here for more details.

@@ -122,7 +122,7 @@ class FixCommand(SimpleCommand):
122
122
  )
123
123
 
124
124
  async def execute(self, args: List[str], context: CommandContext) -> None:
125
- from tunacode.core.agents.main import patch_tool_messages
125
+ from tunacode.core.agents import patch_tool_messages
126
126
 
127
127
  # Count current messages
128
128
  before_count = len(context.state_manager.session.messages)
@@ -152,7 +152,7 @@ class ParseToolsCommand(SimpleCommand):
152
152
  )
153
153
 
154
154
  async def execute(self, args: List[str], context: CommandContext) -> None:
155
- from tunacode.core.agents.main import extract_and_execute_tool_calls
155
+ from tunacode.core.agents import extract_and_execute_tool_calls
156
156
 
157
157
  # Find the last model response in messages
158
158
  messages = context.state_manager.session.messages
@@ -40,7 +40,7 @@ class ClearCommand(SimpleCommand):
40
40
 
41
41
  async def execute(self, args: List[str], context: CommandContext) -> None:
42
42
  # Patch any orphaned tool calls before clearing
43
- from tunacode.core.agents.main import patch_tool_messages
43
+ from tunacode.core.agents import patch_tool_messages
44
44
 
45
45
  patch_tool_messages("Conversation cleared", context.state_manager)
46
46
 
tunacode/cli/repl.py CHANGED
@@ -14,8 +14,8 @@ from pydantic_ai.exceptions import UnexpectedModelBehavior
14
14
 
15
15
  from tunacode.configuration.models import ModelRegistry
16
16
  from tunacode.constants import DEFAULT_CONTEXT_WINDOW
17
- from tunacode.core.agents import main as agent
18
- from tunacode.core.agents.main import patch_tool_messages
17
+ from tunacode.core import agents as agent
18
+ from tunacode.core.agents import patch_tool_messages
19
19
  from tunacode.core.token_usage.api_response_parser import ApiResponseParser
20
20
  from tunacode.core.token_usage.cost_calculator import CostCalculator
21
21
  from tunacode.core.token_usage.usage_tracker import UsageTracker
@@ -238,7 +238,7 @@ async def _handle_plan_approval(state_manager, original_request=None):
238
238
  action()
239
239
  if key == "a" and original_request:
240
240
  await ui.info("🚀 Executing implementation...")
241
- await process_request(
241
+ await execute_repl_request(
242
242
  _transform_to_implementation_request(original_request),
243
243
  state_manager,
244
244
  output=True,
@@ -259,16 +259,16 @@ _command_registry.register_all_default_commands()
259
259
 
260
260
  async def _handle_command(command: str, state_manager: StateManager) -> CommandResult:
261
261
  """Handles a command string using the command registry."""
262
- context = CommandContext(state_manager=state_manager, process_request=process_request)
262
+ context = CommandContext(state_manager=state_manager, process_request=execute_repl_request)
263
263
  try:
264
- _command_registry.set_process_request_callback(process_request)
264
+ _command_registry.set_process_request_callback(execute_repl_request)
265
265
  return await _command_registry.execute(command, context)
266
266
  except ValidationError as e:
267
267
  await ui.error(str(e))
268
268
  return None
269
269
 
270
270
 
271
- async def process_request(text: str, state_manager: StateManager, output: bool = True):
271
+ async def execute_repl_request(text: str, state_manager: StateManager, output: bool = True):
272
272
  """Process input using the agent, handling cancellation safely."""
273
273
  import uuid
274
274
 
@@ -412,6 +412,10 @@ async def process_request(text: str, state_manager: StateManager, output: bool =
412
412
  )
413
413
 
414
414
 
415
+ # Backwards compatibility: exported name expected by external integrations/tests
416
+ process_request = execute_repl_request
417
+
418
+
415
419
  async def warm_code_index():
416
420
  """Pre-warm the code index in background for faster directory operations."""
417
421
  try:
@@ -533,7 +537,7 @@ async def repl(state_manager: StateManager):
533
537
  state_manager.session.operation_cancelled = False
534
538
 
535
539
  state_manager.session.current_task = get_app().create_background_task(
536
- process_request(line, state_manager)
540
+ execute_repl_request(line, state_manager)
537
541
  )
538
542
  await state_manager.session.current_task
539
543
 
@@ -6,6 +6,7 @@ Error recovery utilities for the REPL.
6
6
 
7
7
  import logging
8
8
 
9
+ import tunacode.core.agents as agent_api
9
10
  from tunacode.types import StateManager
10
11
  from tunacode.ui import console as ui
11
12
 
@@ -130,13 +131,12 @@ async def attempt_tool_recovery(e: Exception, state_manager: StateManager) -> bo
130
131
  )
131
132
 
132
133
  try:
133
- from tunacode.core.agents.main import extract_and_execute_tool_calls
134
134
 
135
135
  def tool_callback_with_state(tool_part, _node):
136
136
  return tool_handler(tool_part, state_manager)
137
137
 
138
138
  # This function now returns the number of tools found
139
- tools_found = await extract_and_execute_tool_calls(
139
+ tools_found = await agent_api.extract_and_execute_tool_calls(
140
140
  content_to_parse, tool_callback_with_state, state_manager
141
141
  )
142
142
 
@@ -9,7 +9,7 @@ from asyncio.exceptions import CancelledError
9
9
 
10
10
  from prompt_toolkit.application import run_in_terminal
11
11
 
12
- from tunacode.core.agents.main import patch_tool_messages
12
+ from tunacode.core.agents import patch_tool_messages
13
13
  from tunacode.core.tool_handler import ToolHandler
14
14
  from tunacode.exceptions import UserAbortError
15
15
  from tunacode.types import StateManager
tunacode/constants.py CHANGED
@@ -9,7 +9,7 @@ from enum import Enum
9
9
 
10
10
  # Application info
11
11
  APP_NAME = "TunaCode"
12
- APP_VERSION = "0.0.76.1"
12
+ APP_VERSION = "0.0.76.2"
13
13
 
14
14
 
15
15
  # File patterns
@@ -44,6 +44,7 @@ class ToolName(str, Enum):
44
44
  LIST_DIR = "list_dir"
45
45
  GLOB = "glob"
46
46
  TODO = "todo"
47
+ REACT = "react"
47
48
  EXIT_PLAN_MODE = "exit_plan_mode"
48
49
 
49
50
 
@@ -57,6 +58,7 @@ TOOL_GREP = ToolName.GREP
57
58
  TOOL_LIST_DIR = ToolName.LIST_DIR
58
59
  TOOL_GLOB = ToolName.GLOB
59
60
  TOOL_TODO = ToolName.TODO
61
+ TOOL_REACT = ToolName.REACT
60
62
  TOOL_EXIT_PLAN_MODE = ToolName.EXIT_PLAN_MODE
61
63
 
62
64
  # Tool categorization
@@ -65,6 +67,7 @@ READ_ONLY_TOOLS = [
65
67
  ToolName.GREP,
66
68
  ToolName.LIST_DIR,
67
69
  ToolName.GLOB,
70
+ ToolName.REACT,
68
71
  ToolName.EXIT_PLAN_MODE,
69
72
  ]
70
73
  WRITE_TOOLS = [ToolName.WRITE_FILE, ToolName.UPDATE_FILE]
@@ -1,8 +1,45 @@
1
- """Agent helper modules."""
1
+ """Public entry points for TunaCode agent orchestration."""
2
2
 
3
- from .main import get_or_create_agent, process_request
3
+ from . import main as main
4
+ from .agent_components import (
5
+ AgentRunWithState,
6
+ AgentRunWrapper,
7
+ ResponseState,
8
+ SimpleResult,
9
+ ToolBuffer,
10
+ _process_node,
11
+ check_task_completion,
12
+ execute_tools_parallel,
13
+ extract_and_execute_tool_calls,
14
+ get_model_messages,
15
+ get_or_create_agent,
16
+ parse_json_tool_calls,
17
+ patch_tool_messages,
18
+ )
19
+ from .main import (
20
+ check_query_satisfaction,
21
+ get_agent_tool,
22
+ get_mcp_servers,
23
+ process_request,
24
+ )
4
25
 
5
26
  __all__ = [
6
27
  "process_request",
7
28
  "get_or_create_agent",
29
+ "extract_and_execute_tool_calls",
30
+ "parse_json_tool_calls",
31
+ "get_model_messages",
32
+ "patch_tool_messages",
33
+ "_process_node",
34
+ "ResponseState",
35
+ "SimpleResult",
36
+ "AgentRunWrapper",
37
+ "AgentRunWithState",
38
+ "ToolBuffer",
39
+ "check_task_completion",
40
+ "execute_tools_parallel",
41
+ "get_mcp_servers",
42
+ "check_query_satisfaction",
43
+ "get_agent_tool",
44
+ "main",
8
45
  ]
@@ -1,5 +1,7 @@
1
1
  """Agent components package for modular agent functionality."""
2
2
 
3
+ from tunacode.ui.tool_descriptions import get_batch_description
4
+
3
5
  from .agent_config import get_or_create_agent
4
6
  from .agent_helpers import (
5
7
  create_empty_response_message,
@@ -17,6 +19,7 @@ from .message_handler import get_model_messages, patch_tool_messages
17
19
  from .node_processor import _process_node
18
20
  from .response_state import ResponseState
19
21
  from .result_wrapper import AgentRunWithState, AgentRunWrapper, SimpleResult
22
+ from .streaming import stream_model_request_node
20
23
  from .task_completion import check_task_completion
21
24
  from .tool_buffer import ToolBuffer
22
25
  from .tool_executor import execute_tools_parallel
@@ -44,4 +47,6 @@ __all__ = [
44
47
  "get_tool_description",
45
48
  "get_tool_summary",
46
49
  "get_user_prompt_part_class",
50
+ "stream_model_request_node",
51
+ "get_batch_description",
47
52
  ]
@@ -3,6 +3,11 @@
3
3
  import re
4
4
  from typing import Tuple
5
5
 
6
+ _COMPLETION_MARKERS = (
7
+ re.compile(r"^\s*TUNACODE\s+DONE:\s*", re.IGNORECASE),
8
+ re.compile(r"^\s*TUNACODE[_\s]+TASK_COMPLETE\s*:?[\s]*", re.IGNORECASE),
9
+ )
10
+
6
11
 
7
12
  def check_task_completion(content: str) -> Tuple[bool, str]:
8
13
  """
@@ -21,12 +26,16 @@ def check_task_completion(content: str) -> Tuple[bool, str]:
21
26
 
22
27
  lines = content.split("\n")
23
28
 
24
- # New marker: any line starting with "TUNACODE DONE:" (case-insensitive, allow leading whitespace)
25
- done_pattern = re.compile(r"^\s*TUNACODE\s+DONE:\s*", re.IGNORECASE)
26
29
  for idx, line in enumerate(lines):
27
- if done_pattern.match(line):
28
- # Remove the marker line and return remaining content
29
- cleaned = "\n".join(lines[:idx] + lines[idx + 1 :]).strip()
30
- return True, cleaned
30
+ for pattern in _COMPLETION_MARKERS:
31
+ match = pattern.match(line)
32
+ if match:
33
+ remainder = line[match.end() :].strip()
34
+ cleaned_lines = lines[:idx]
35
+ if remainder:
36
+ cleaned_lines.append(remainder)
37
+ cleaned_lines.extend(lines[idx + 1 :])
38
+ cleaned = "\n".join(cleaned_lines).strip()
39
+ return True, cleaned
31
40
 
32
41
  return False, content