tunacode-cli 0.0.47__py3-none-any.whl → 0.0.48__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.

@@ -1,20 +1,13 @@
1
1
  import asyncio
2
2
  import importlib
3
3
  import json
4
- import logging
5
4
  import os
6
5
  import re
7
6
  from collections.abc import Iterator
8
7
  from datetime import datetime, timezone
9
8
  from typing import Any
10
9
 
11
- from tunacode.constants import (
12
- JSON_PARSE_BASE_DELAY,
13
- JSON_PARSE_MAX_DELAY,
14
- JSON_PARSE_MAX_RETRIES,
15
- READ_ONLY_TOOLS,
16
- )
17
- from tunacode.exceptions import ToolBatchingJSONError
10
+ from tunacode.constants import READ_ONLY_TOOLS
18
11
  from tunacode.types import (
19
12
  ErrorMessage,
20
13
  StateManager,
@@ -23,9 +16,6 @@ from tunacode.types import (
23
16
  ToolName,
24
17
  )
25
18
  from tunacode.ui import console as ui
26
- from tunacode.utils.retry import retry_json_parse_async
27
-
28
- logger = logging.getLogger(__name__)
29
19
 
30
20
 
31
21
  # Lazy import for Agent and Tool
@@ -177,28 +167,11 @@ async def parse_json_tool_calls(
177
167
  if brace_count == 0 and start_pos != -1:
178
168
  potential_json = text[start_pos : i + 1]
179
169
  try:
180
- # Use retry logic for JSON parsing
181
- parsed = await retry_json_parse_async(
182
- potential_json,
183
- max_retries=JSON_PARSE_MAX_RETRIES,
184
- base_delay=JSON_PARSE_BASE_DELAY,
185
- max_delay=JSON_PARSE_MAX_DELAY,
186
- )
170
+ parsed = json.loads(potential_json)
187
171
  if isinstance(parsed, dict) and "tool" in parsed and "args" in parsed:
188
172
  potential_jsons.append((parsed["tool"], parsed["args"]))
189
- except json.JSONDecodeError as e:
190
- # After all retries failed
191
- logger.error(f"JSON parsing failed after {JSON_PARSE_MAX_RETRIES} retries: {e}")
192
- if state_manager.session.show_thoughts:
193
- await ui.error(
194
- f"Failed to parse tool JSON after {JSON_PARSE_MAX_RETRIES} retries"
195
- )
196
- # Raise custom exception for better error handling
197
- raise ToolBatchingJSONError(
198
- json_content=potential_json,
199
- retry_count=JSON_PARSE_MAX_RETRIES,
200
- original_error=e,
201
- ) from e
173
+ except json.JSONDecodeError:
174
+ pass
202
175
  start_pos = -1
203
176
 
204
177
  matches = potential_jsons
@@ -247,13 +220,7 @@ async def extract_and_execute_tool_calls(
247
220
 
248
221
  for match in code_matches:
249
222
  try:
250
- # Use retry logic for JSON parsing in code blocks
251
- tool_data = await retry_json_parse_async(
252
- match,
253
- max_retries=JSON_PARSE_MAX_RETRIES,
254
- base_delay=JSON_PARSE_BASE_DELAY,
255
- max_delay=JSON_PARSE_MAX_DELAY,
256
- )
223
+ tool_data = json.loads(match)
257
224
  if "tool" in tool_data and "args" in tool_data:
258
225
 
259
226
  class MockToolCall:
@@ -273,22 +240,7 @@ async def extract_and_execute_tool_calls(
273
240
  if state_manager.session.show_thoughts:
274
241
  await ui.muted(f"FALLBACK: Executed {tool_data['tool']} from code block")
275
242
 
276
- except json.JSONDecodeError as e:
277
- # After all retries failed
278
- logger.error(
279
- f"Code block JSON parsing failed after {JSON_PARSE_MAX_RETRIES} retries: {e}"
280
- )
281
- if state_manager.session.show_thoughts:
282
- await ui.error(
283
- f"Failed to parse code block tool JSON after {JSON_PARSE_MAX_RETRIES} retries"
284
- )
285
- # Raise custom exception for better error handling
286
- raise ToolBatchingJSONError(
287
- json_content=match,
288
- retry_count=JSON_PARSE_MAX_RETRIES,
289
- original_error=e,
290
- ) from e
291
- except (KeyError, Exception) as e:
243
+ except (json.JSONDecodeError, KeyError, Exception) as e:
292
244
  if state_manager.session.show_thoughts:
293
245
  await ui.error(f"Error parsing code block tool call: {e!s}")
294
246
 
tunacode/core/state.py CHANGED
@@ -68,13 +68,6 @@ class SessionState:
68
68
  "cost": 0.0,
69
69
  }
70
70
  )
71
- # Recursive execution tracking
72
- current_recursion_depth: int = 0
73
- max_recursion_depth: int = 5
74
- parent_task_id: Optional[str] = None
75
- task_hierarchy: dict[str, Any] = field(default_factory=dict)
76
- iteration_budgets: dict[str, int] = field(default_factory=dict)
77
- recursive_context_stack: list[dict[str, Any]] = field(default_factory=list)
78
71
 
79
72
  def update_token_count(self):
80
73
  """Calculates the total token count from messages and files in context."""
@@ -105,40 +98,6 @@ class StateManager:
105
98
  todo.completed_at = datetime.now()
106
99
  break
107
100
 
108
- def push_recursive_context(self, context: dict[str, Any]) -> None:
109
- """Push a new context onto the recursive execution stack."""
110
- self._session.recursive_context_stack.append(context)
111
- self._session.current_recursion_depth += 1
112
-
113
- def pop_recursive_context(self) -> Optional[dict[str, Any]]:
114
- """Pop the current context from the recursive execution stack."""
115
- if self._session.recursive_context_stack:
116
- self._session.current_recursion_depth = max(
117
- 0, self._session.current_recursion_depth - 1
118
- )
119
- return self._session.recursive_context_stack.pop()
120
- return None
121
-
122
- def set_task_iteration_budget(self, task_id: str, budget: int) -> None:
123
- """Set the iteration budget for a specific task."""
124
- self._session.iteration_budgets[task_id] = budget
125
-
126
- def get_task_iteration_budget(self, task_id: str) -> int:
127
- """Get the iteration budget for a specific task."""
128
- return self._session.iteration_budgets.get(task_id, 10) # Default to 10
129
-
130
- def can_recurse_deeper(self) -> bool:
131
- """Check if we can recurse deeper without exceeding limits."""
132
- return self._session.current_recursion_depth < self._session.max_recursion_depth
133
-
134
- def reset_recursive_state(self) -> None:
135
- """Reset all recursive execution state."""
136
- self._session.current_recursion_depth = 0
137
- self._session.parent_task_id = None
138
- self._session.task_hierarchy.clear()
139
- self._session.iteration_budgets.clear()
140
- self._session.recursive_context_stack.clear()
141
-
142
101
  def remove_todo(self, todo_id: str) -> None:
143
102
  self._session.todos = [todo for todo in self._session.todos if todo.id != todo_id]
144
103
 
tunacode/exceptions.py CHANGED
@@ -114,26 +114,3 @@ class TooBroadPatternError(ToolExecutionError):
114
114
  f"Pattern '{pattern}' is too broad - no matches found within {timeout_seconds}s. "
115
115
  "Please use a more specific pattern.",
116
116
  )
117
-
118
-
119
- class ToolBatchingJSONError(TunaCodeError):
120
- """Raised when JSON parsing fails during tool batching after all retries are exhausted."""
121
-
122
- def __init__(
123
- self,
124
- json_content: str,
125
- retry_count: int,
126
- original_error: OriginalError = None,
127
- ):
128
- self.json_content = json_content
129
- self.retry_count = retry_count
130
- self.original_error = original_error
131
-
132
- # Truncate JSON content for display if too long
133
- display_content = json_content[:100] + "..." if len(json_content) > 100 else json_content
134
-
135
- super().__init__(
136
- f"The model is having issues with tool batching. "
137
- f"JSON parsing failed after {retry_count} retries. "
138
- f"Invalid JSON: {display_content}"
139
- )
@@ -0,0 +1,45 @@
1
+ # DSPy Task Planning Prompt
2
+
3
+ This prompt is automatically generated and optimized by DSPy for TunaCode's complex task planning.
4
+
5
+ ## Format
6
+
7
+ Given the fields `complex_request`, produce the fields `subtasks_with_tools`, `total_tool_calls`, `requires_todo`, `parallelization_opportunities`.
8
+
9
+ ---
10
+
11
+ Follow the following format.
12
+
13
+ Complex Request: A complex task that needs breakdown
14
+ Reasoning: Let's think step by step in order to ${produce the answer}. We need to break this down into manageable subtasks...
15
+ Subtasks With Tools: JSON array of {task, tools, priority} objects
16
+ Total Tool Calls: Estimated total number of tool calls
17
+ Requires Todo: Whether todo tool should be used
18
+ Parallelization Opportunities: Number of parallel execution opportunities
19
+
20
+ ---
21
+
22
+ ## Learned Example (Selected by DSPy)
23
+
24
+ ### Example: Authentication System Implementation
25
+ Complex Request: Implement user authentication system with JWT tokens
26
+ Reasoning: Let's think step by step. This is a complex implementation task that requires multiple components. First, I need to analyze the current application structure to understand how to integrate authentication. Then I'll design the user model and database schema. Next, I'll create the authentication endpoints for registration and login. I'll need to implement JWT token generation and validation. Finally, I'll add tests to ensure everything works correctly. Several of these tasks can be done in parallel once the initial analysis is complete.
27
+ Subtasks With Tools: [{"task": "Analyze current app structure", "tools": ["list_dir", "grep", "read_file"], "priority": "high"}, {"task": "Design user model", "tools": ["write_file"], "priority": "high"}, {"task": "Create auth endpoints", "tools": ["write_file", "update_file"], "priority": "high"}, {"task": "Add JWT tokens", "tools": ["write_file", "grep"], "priority": "high"}, {"task": "Write tests", "tools": ["write_file", "run_command"], "priority": "medium"}]
28
+ Total Tool Calls: 15
29
+ Requires Todo: true
30
+ Parallelization Opportunities: 3
31
+
32
+ ---
33
+
34
+ ## Key Patterns for Complex Tasks
35
+
36
+ 1. **Break Down First**: Start with analysis/exploration before implementation
37
+ 2. **Priority Levels**: High for core functionality, medium for tests/docs, low for nice-to-haves
38
+ 3. **Tool Grouping**: Group related tools together for each subtask
39
+ 4. **Todo Usage**: Use todo tool for tasks with 5+ subtasks
40
+ 5. **Parallelization**: Identify independent subtasks that can run concurrently
41
+
42
+ ---
43
+
44
+ Complex Request: ${complex_request}
45
+ Reasoning: Let's think step by step...
@@ -0,0 +1,58 @@
1
+ # DSPy Tool Selection Prompt
2
+
3
+ This prompt is automatically generated and optimized by DSPy for TunaCode's tool selection.
4
+
5
+ ## Format
6
+
7
+ Given the fields `user_request`, `current_directory`, produce the fields `tools_json`, `requires_confirmation`, `reasoning`.
8
+
9
+ ---
10
+
11
+ Follow the following format.
12
+
13
+ User Request: The user's request or task
14
+ Current Directory: Current working directory context
15
+ Reasoning: Let's think step by step in order to ${produce the answer}. We ...
16
+ Tools Json: JSON array of tool calls with batch grouping, e.g. [[tool1, tool2, tool3], [tool4]]
17
+ Requires Confirmation: Whether any tools require user confirmation
18
+
19
+ ---
20
+
21
+ ## Learned Examples (Automatically Selected by DSPy)
22
+
23
+ ### Example 1: Searching for Implementation
24
+ User Request: Show me the authentication system implementation
25
+ Current Directory: .
26
+ Reasoning: Let's think step by step. To show the authentication implementation, I need to search for auth-related files across the codebase. I'll use grep to find files containing 'auth', list the auth directory if it exists, and use glob to find all auth-related Python files. These are all read-only operations that can be executed in parallel.
27
+ Tools Json: [["grep(\"auth\", \"src/\")", "list_dir(\"src/auth/\")", "glob(\"**/*auth*.py\")"]]
28
+ Requires Confirmation: false
29
+
30
+ ### Example 2: Reading Multiple Files (Optimal Batching)
31
+ User Request: Read all config files and the main module
32
+ Current Directory: .
33
+ Reasoning: Let's think step by step. I need to read multiple specific files. All of these are read operations that can be batched together for parallel execution. I'll batch them in a group of 4 for optimal performance.
34
+ Tools Json: [["read_file(\"config.json\")", "read_file(\"settings.py\")", "read_file(\".env\")", "read_file(\"main.py\")"]]
35
+ Requires Confirmation: false
36
+
37
+ ### Example 3: Search, Read, then Modify Pattern
38
+ User Request: Find the bug in validation and fix it
39
+ Current Directory: .
40
+ Reasoning: Let's think step by step. First, I need to search for validation-related code and errors. I'll use grep to search for error patterns and validation code, and list the validators directory. These search operations can be parallelized. After finding the issue, I'll need to read the specific file and then update it to fix the bug.
41
+ Tools Json: [["grep(\"error\", \"logs/\")", "grep(\"validation\", \"src/\")", "list_dir(\"src/validators/\")"], ["read_file(\"src/validators/user.py\")"], ["update_file(\"src/validators/user.py\", \"old\", \"new\")"]]
42
+ Requires Confirmation: true
43
+
44
+ ---
45
+
46
+ ## Key Patterns Learned by DSPy
47
+
48
+ 1. **3-4 Tool Batching**: Optimal batch size for parallel read-only operations
49
+ 2. **Read-Only Parallelization**: grep, list_dir, glob, read_file can run in parallel
50
+ 3. **Sequential Writes**: write_file, update_file, run_command, bash must run sequentially
51
+ 4. **Confirmation Required**: Any write/execute operation needs confirmation
52
+ 5. **Search → Read → Modify**: Common pattern for debugging and fixes
53
+
54
+ ---
55
+
56
+ User Request: ${user_request}
57
+ Current Directory: ${current_directory}
58
+ Reasoning: Let's think step by step...
tunacode/ui/input.py CHANGED
@@ -75,13 +75,12 @@ async def multiline_input(
75
75
  state_manager: Optional[StateManager] = None, command_registry=None
76
76
  ) -> str:
77
77
  """Get multiline input from the user with @file completion and highlighting."""
78
- kb = create_key_bindings(state_manager)
78
+ kb = create_key_bindings()
79
79
  placeholder = formatted_text(
80
80
  (
81
81
  "<darkgrey>"
82
82
  "<bold>Enter</bold> to submit • "
83
83
  "<bold>Esc + Enter</bold> for new line • "
84
- "<bold>Esc</bold> to cancel • "
85
84
  "<bold>/help</bold> for commands"
86
85
  "</darkgrey>"
87
86
  )
@@ -1,15 +1,9 @@
1
1
  """Key binding handlers for TunaCode UI."""
2
2
 
3
- import logging
4
-
5
3
  from prompt_toolkit.key_binding import KeyBindings
6
4
 
7
- from ..core.state import StateManager
8
-
9
- logger = logging.getLogger(__name__)
10
5
 
11
-
12
- def create_key_bindings(state_manager: StateManager = None) -> KeyBindings:
6
+ def create_key_bindings() -> KeyBindings:
13
7
  """Create and configure key bindings for the UI."""
14
8
  kb = KeyBindings()
15
9
 
@@ -28,14 +22,4 @@ def create_key_bindings(state_manager: StateManager = None) -> KeyBindings:
28
22
  """Insert a newline when escape then enter is pressed."""
29
23
  event.current_buffer.insert_text("\n")
30
24
 
31
- @kb.add("escape")
32
- def _escape(event):
33
- """Immediately interrupts the current operation."""
34
- current_task = state_manager.session.current_task if state_manager else None
35
- if current_task and not current_task.done():
36
- logger.debug("Interrupting current task")
37
- current_task.cancel()
38
- else:
39
- logger.debug("Escape key pressed outside task context")
40
-
41
25
  return kb
tunacode/ui/panels.py CHANGED
@@ -9,7 +9,6 @@ from rich.padding import Padding
9
9
  from rich.panel import Panel
10
10
  from rich.pretty import Pretty
11
11
  from rich.table import Table
12
- from rich.text import Text
13
12
 
14
13
  from tunacode.configuration.models import ModelRegistry
15
14
  from tunacode.constants import (
@@ -90,15 +89,9 @@ class StreamingAgentPanel:
90
89
  # Use the UI_THINKING_MESSAGE constant instead of hardcoded text
91
90
  from tunacode.constants import UI_THINKING_MESSAGE
92
91
 
93
- # If no content, show thinking message with Rich markup
94
- if not self.content:
95
- content_to_display = Text.from_markup(UI_THINKING_MESSAGE)
96
- else:
97
- # Normal content is markdown
98
- content_to_display = Markdown(self.content)
99
-
92
+ markdown_content = Markdown(self.content or UI_THINKING_MESSAGE)
100
93
  panel_obj = Panel(
101
- Padding(content_to_display, (0, 1, 0, 1)),
94
+ Padding(markdown_content, (0, 1, 0, 1)),
102
95
  title=f"[bold]{self.title}[/bold]",
103
96
  title_align="left",
104
97
  border_style=colors.primary,
@@ -4,7 +4,8 @@ import logging
4
4
  from functools import lru_cache
5
5
  from typing import Optional
6
6
 
7
- # Get logger for this module
7
+ # Configure logging
8
+ logging.basicConfig(level=logging.INFO)
8
9
  logger = logging.getLogger(__name__)
9
10
 
10
11
  # Cache for tokenizer encodings
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.47
3
+ Version: 0.0.48
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License: MIT
@@ -37,7 +37,7 @@ Requires-Dist: textual-dev; extra == "dev"
37
37
  Requires-Dist: pre-commit; extra == "dev"
38
38
  Dynamic: license-file
39
39
 
40
- # TunaCode
40
+ # TunaCode CLI
41
41
 
42
42
  <div align="center">
43
43
 
@@ -48,7 +48,7 @@ Dynamic: license-file
48
48
 
49
49
  **AI-powered CLI coding assistant**
50
50
 
51
- ![TunaCode Example](assets/tunacode_example.png)
51
+ ![Demo](docs/assets/demo.gif)
52
52
 
53
53
  </div>
54
54
 
@@ -1,13 +1,13 @@
1
1
  tunacode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- tunacode/constants.py,sha256=833fgfAmkcJmU1RmSYDhGCOzoU-eUMdgbcfBBwUQOZ4,5168
2
+ tunacode/constants.py,sha256=SnkxDDf4YNG66RWs2ByAN5aIZra8ubkzlXv5-OE1ZZU,4993
3
3
  tunacode/context.py,sha256=_gXVCyjU052jlyRAl9tklZSwl5U_zI_EIX8XN87VVWE,2786
4
- tunacode/exceptions.py,sha256=oDO1SVKOgjcKIylwqdbqh_g5my4roU5mB9Nv4n_Vb0s,3877
4
+ tunacode/exceptions.py,sha256=mTWXuWyr1k16CGLWN2tsthDGi7lbx1JK0ekIqogYDP8,3105
5
5
  tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  tunacode/setup.py,sha256=XPt4eAK-qcIZQv64jGZ_ryxcImDwps9OmXjJfIS1xcs,1899
7
7
  tunacode/types.py,sha256=Czq7jYXHq7fZQtyqkCN5_7eEu1wyYUcB50C6v3sTWDw,8188
8
8
  tunacode/cli/__init__.py,sha256=zgs0UbAck8hfvhYsWhWOfBe5oK09ug2De1r4RuQZREA,55
9
- tunacode/cli/main.py,sha256=erP6jNXcxVQOVn8sm6uNaLEAYevniVXl6Sem872mW68,2755
10
- tunacode/cli/repl.py,sha256=rSsUievdOdTkxzHNIEgUHbuWbk0ki78743Wz5hVFe9s,18917
9
+ tunacode/cli/main.py,sha256=ypefhvSt9hXzNOv0WpR-PlkUOSGadvcFbUIRT13n9oo,2619
10
+ tunacode/cli/repl.py,sha256=CMvl5wlxj7hr45mxil26fwbmWpDYxRsRVS9aIGJvKK0,18525
11
11
  tunacode/cli/commands/__init__.py,sha256=zmE9JcJ9Qd2xJhgdS4jMDJOoZsrAZmL5MAFxbKkk7F8,1670
12
12
  tunacode/cli/commands/base.py,sha256=GxUuDsDSpz0iXryy8MrEw88UM3C3yxL__kDK1QhshoA,2517
13
13
  tunacode/cli/commands/registry.py,sha256=XVuLpp5S4Fw7GfIZfLrVZFo4jMLMNmYNpYN7xWgXyOk,8223
@@ -19,25 +19,21 @@ tunacode/cli/commands/implementations/model.py,sha256=uthx6IX9KwgwywNTDklkJpqCba
19
19
  tunacode/cli/commands/implementations/system.py,sha256=2cGw5iCJO3aNhXTFF28CgAIyLgslvHmpfyL2ZHVB6oQ,7903
20
20
  tunacode/cli/commands/implementations/todo.py,sha256=Dtz5bgcuK2VXGPWEBBZQgnWUMYkRXNzTGf_qkVPLF2U,8125
21
21
  tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
22
- tunacode/configuration/defaults.py,sha256=lK_qf3BexmoQh7lbtxYG_ef0Kq3WyiLGOYmiVDO_amQ,840
22
+ tunacode/configuration/defaults.py,sha256=Qny32BhbSeRBrE9baWZcAit3XFXgWuXFMDJUZudj55M,922
23
23
  tunacode/configuration/models.py,sha256=buH8ZquvcYI3OQBDIZeJ08cu00rSCeNABtUwl3VQS0E,4103
24
24
  tunacode/configuration/settings.py,sha256=KoN0u6GG3Hh_TWt02D_wpRfbACYri3gCDTXHtJfHl2w,994
25
25
  tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  tunacode/core/code_index.py,sha256=jgAx3lSWP_DwnyiP5Jkm1YvX4JJyI4teMzlNrJSpEOA,15661
27
- tunacode/core/state.py,sha256=2lsDgq0uIIc_MnXPE9SG_1fYFBDWWlgqgqm2Ik1iFBs,5599
27
+ tunacode/core/state.py,sha256=hOLuvojJksd3GEezNT6jLPAsCcI-mZKldUUvlP4IKjw,3641
28
28
  tunacode/core/tool_handler.py,sha256=BPjR013OOO0cLXPdLeL2FDK0ixUwOYu59FfHdcdFhp4,2277
29
29
  tunacode/core/agents/__init__.py,sha256=UUJiPYb91arwziSpjd7vIk7XNGA_4HQbsOIbskSqevA,149
30
- tunacode/core/agents/main.py,sha256=BRy3joJnn4GpUW47PyhiKK1JLMSamlK7wDMLwAGzSG0,47441
31
- tunacode/core/agents/utils.py,sha256=7kJAiUlkyWO3-b4T07XsGgycVrcNhv3NEPLdaktBnP4,12847
30
+ tunacode/core/agents/dspy_integration.py,sha256=h3gJ-qr0fXpB2CRaU-MVv_8xG--ah-8nra7WO960Gbo,9152
31
+ tunacode/core/agents/dspy_tunacode.py,sha256=tIluqDsHAv3nbNYtqFh4oyZA9yqMrnyY2G-QOpkTLCs,17398
32
+ tunacode/core/agents/main.py,sha256=UOMJTkuhMEMVmV0bGWU2cEkiukdcLAKby-9AOaIGc0Y,43102
33
+ tunacode/core/agents/utils.py,sha256=VaNsPB2l1dAP-VlS_QLRKvCb4NW0pXNRoxkh12AGXAg,10744
32
34
  tunacode/core/background/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
35
  tunacode/core/background/manager.py,sha256=rJdl3eDLTQwjbT7VhxXcJbZopCNR3M8ZGMbmeVnwwMc,1126
34
36
  tunacode/core/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- tunacode/core/recursive/__init__.py,sha256=S9_dN0faJqam3Pnaum9PRC8Hd90bpES8syFgAD8-QbI,446
36
- tunacode/core/recursive/aggregator.py,sha256=KlWajEyT8OokWeY6ZwQ4EsVu05V4KeH3o2cYUz-Ce1Y,15725
37
- tunacode/core/recursive/budget.py,sha256=0wY6xSrZKmudUwthwX1mlcF5yat2_y3fNu5shX_IzvA,14131
38
- tunacode/core/recursive/decomposer.py,sha256=k8rgaPEMMb2mZ9W0m_Yg0oEBqbYpqDnK0zyTkx6eTPs,14550
39
- tunacode/core/recursive/executor.py,sha256=7taFsjYjSfL8OUQLM1ZVn9Xix7YoputFBAZSo9tDtDM,16646
40
- tunacode/core/recursive/hierarchy.py,sha256=67tdDCKB5mTSn6VIwm-knEHB_VKUkeljFdwH62U5chE,15648
41
37
  tunacode/core/setup/__init__.py,sha256=lzdpY6rIGf9DDlDBDGFvQZaSOQeFsNglHbkpq1-GtU8,376
42
38
  tunacode/core/setup/agent_setup.py,sha256=trELO8cPnWo36BBnYmXDEnDPdhBg0p-VLnx9A8hSSSQ,1401
43
39
  tunacode/core/setup/base.py,sha256=cbyT2-xK2mWgH4EO17VfM_OM2bj0kT895NW2jSXbe3c,968
@@ -48,6 +44,8 @@ tunacode/core/setup/git_safety_setup.py,sha256=CRIqrQt0QUJQRS344njty_iCqTorrDhHl
48
44
  tunacode/core/token_usage/api_response_parser.py,sha256=CTtqGaFaxpkzkW3TEbe00QJzyRULpWN1EQxIYMleseg,1622
49
45
  tunacode/core/token_usage/cost_calculator.py,sha256=RjO-O0JENBuGOrWP7QgBZlZxeXC-PAIr8tj_9p_BxOU,2058
50
46
  tunacode/core/token_usage/usage_tracker.py,sha256=kuAjUCyQkFykPy5mqsLRbKhZW298pyiCuFGn-ptBpy4,4657
47
+ tunacode/prompts/dspy_task_planning.md,sha256=RNimkmnFcNgskwQrguGb3wB8A-Zngp6Qc9lXfPj61OU,2512
48
+ tunacode/prompts/dspy_tool_selection.md,sha256=CPBHrI4QlWD2mzNdoVkFK7GydgCLW9Bi20sD8ZEysRo,3070
51
49
  tunacode/prompts/system.md,sha256=hXpjZ8Yiv2Acr2_6EmC2uOklP8FbmvyYR9oais-1KLk,16290
52
50
  tunacode/services/__init__.py,sha256=w_E8QK6RnvKSvU866eDe8BCRV26rAm4d3R-Yg06OWCU,19
53
51
  tunacode/services/mcp.py,sha256=R48X73KQjQ9vwhBrtbWHSBl-4K99QXmbIhh5J_1Gezo,3046
@@ -68,13 +66,12 @@ tunacode/ui/completers.py,sha256=Jx1zyCESwdm_4ZopvCBtb0bCJF-bRy8aBWG2yhPQtDc,487
68
66
  tunacode/ui/console.py,sha256=icb7uYrV8XmZg9glreEy5MrvDkmrKxbf_ZkNqElN1uE,2120
69
67
  tunacode/ui/constants.py,sha256=A76B_KpM8jCuBYRg4cPmhi8_j6LLyWttO7_jjv47r3w,421
70
68
  tunacode/ui/decorators.py,sha256=e2KM-_pI5EKHa2M045IjUe4rPkTboxaKHXJT0K3461g,1914
71
- tunacode/ui/input.py,sha256=x_7G9VVdvydpEk2kcyG-OBKND5lL5ADbiGcDXF1n5UA,3014
72
- tunacode/ui/keybindings.py,sha256=tn0q0eRw72j8xPWX0673Xc-vmwlvFEyuhy3C451ntfE,1233
69
+ tunacode/ui/input.py,sha256=E_zAJqNYoAVFA-j4xE9Qgs22y-GrdSZNqiseX-Or0ho,2955
70
+ tunacode/ui/keybindings.py,sha256=h0MlD73CW_3i2dQzb9EFSPkqy0raZ_isgjxUiA9u6ts,691
73
71
  tunacode/ui/lexers.py,sha256=tmg4ic1enyTRLzanN5QPP7D_0n12YjX_8ZhsffzhXA4,1340
74
72
  tunacode/ui/output.py,sha256=51O0VHajte4dXHK5Az5SSP4IOb2q5SbCwvqdAoxyg7c,5665
75
- tunacode/ui/panels.py,sha256=dBZEVIJqliWreY-hz6HpW5rdBmPOJZ6sPrv8KQ3eNhk,8570
73
+ tunacode/ui/panels.py,sha256=ckL-TYxYWlpBAFj8SC9Od8vrW7Kf5N92bZRYBWR14jE,8338
76
74
  tunacode/ui/prompt_manager.py,sha256=U2cntB34vm-YwOj3gzFRUK362zccrz8pigQfpxr5sv8,4650
77
- tunacode/ui/recursive_progress.py,sha256=V0dGpJWt19TVArOYcQ3Lki8cR3ZepFT6iGwnChSFhFI,12906
78
75
  tunacode/ui/tool_ui.py,sha256=qp1aZUpLO5UOdJziY8tw0URC8gjoWoSKdGu5y2wuTUU,7013
79
76
  tunacode/ui/utils.py,sha256=yvoCTz8AOdRfV0XIqUX3sgg88g_wntV9yhnQP6WzAVs,114
80
77
  tunacode/ui/validators.py,sha256=MMIMT1I2v0l2jIy-gxX_4GSApvUTi8XWIOACr_dmoBA,758
@@ -84,16 +81,15 @@ tunacode/utils/diff_utils.py,sha256=V9QqQ0q4MfabVTnWptF3IXDp3estnfOKcJtDe_Sj14I,
84
81
  tunacode/utils/file_utils.py,sha256=AXiAJ_idtlmXEi9pMvwtfPy9Ys3yK-F4K7qb_NpwonU,923
85
82
  tunacode/utils/import_cache.py,sha256=q_xjJbtju05YbFopLDSkIo1hOtCx3DOTl3GQE5FFDgs,295
86
83
  tunacode/utils/message_utils.py,sha256=kM6VSS2Dudjplie009khHgmIRjDoBUzv6tvHcYNDAAE,586
87
- tunacode/utils/retry.py,sha256=AHdUzY6m-mwlT4OPXdtWWMAafL_NeS7JAMORGyM8c5k,4931
88
84
  tunacode/utils/ripgrep.py,sha256=AXUs2FFt0A7KBV996deS8wreIlUzKOlAHJmwrcAr4No,583
89
85
  tunacode/utils/security.py,sha256=e_zo9VmcOKFjgFMr9GOBIFhAmND4PBlJZgY7zqnsGjI,6548
90
86
  tunacode/utils/system.py,sha256=FSoibTIH0eybs4oNzbYyufIiV6gb77QaeY2yGqW39AY,11381
91
87
  tunacode/utils/text_utils.py,sha256=6YBD9QfkDO44-6jxnwRWIpmfIifPG-NqMzy_O2NAouc,7277
92
- tunacode/utils/token_counter.py,sha256=lLbkrNUraRQn5RMhwnGurqq1RHFDyn4AaFhruONWIxo,2690
88
+ tunacode/utils/token_counter.py,sha256=l5KemYLfsypAtAF_YrDtVKFtBEghydS_MA8c-8mpPvM,2721
93
89
  tunacode/utils/user_configuration.py,sha256=Ilz8dpGVJDBE2iLWHAPT0xR8D51VRKV3kIbsAz8Bboc,3275
94
- tunacode_cli-0.0.47.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
95
- tunacode_cli-0.0.47.dist-info/METADATA,sha256=oHfTMPtEUgbgVd7Nm0bb39wAKAuPKRHskBpZmDnBxMM,5902
96
- tunacode_cli-0.0.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
- tunacode_cli-0.0.47.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
98
- tunacode_cli-0.0.47.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
99
- tunacode_cli-0.0.47.dist-info/RECORD,,
90
+ tunacode_cli-0.0.48.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
91
+ tunacode_cli-0.0.48.dist-info/METADATA,sha256=JGqtbkLjVdJIz9glj3II8lPbNj2kXvXQdrpjra2z-Nw,5887
92
+ tunacode_cli-0.0.48.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
93
+ tunacode_cli-0.0.48.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
94
+ tunacode_cli-0.0.48.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
95
+ tunacode_cli-0.0.48.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- """Module: tunacode.core.recursive
2
-
3
- Recursive task execution system for complex task decomposition and execution.
4
- """
5
-
6
- from .aggregator import ResultAggregator
7
- from .budget import BudgetManager
8
- from .decomposer import TaskDecomposer
9
- from .executor import RecursiveTaskExecutor
10
- from .hierarchy import TaskHierarchy
11
-
12
- __all__ = [
13
- "RecursiveTaskExecutor",
14
- "TaskDecomposer",
15
- "TaskHierarchy",
16
- "BudgetManager",
17
- "ResultAggregator",
18
- ]