tunacode-cli 0.0.53__py3-none-any.whl → 0.0.55__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.
- tunacode/cli/commands/__init__.py +2 -0
- tunacode/cli/commands/registry.py +4 -1
- tunacode/cli/repl.py +23 -7
- tunacode/cli/repl_components/tool_executor.py +6 -4
- tunacode/constants.py +1 -1
- tunacode/core/agents/agent_components/__init__.py +20 -0
- tunacode/core/agents/agent_components/agent_helpers.py +219 -0
- tunacode/core/agents/agent_components/node_processor.py +39 -74
- tunacode/core/agents/agent_components/truncation_checker.py +81 -0
- tunacode/core/agents/main.py +86 -312
- tunacode/core/state.py +7 -3
- tunacode/prompts/system.md +5 -4
- tunacode/tools/grep.py +12 -1
- tunacode/ui/console.py +2 -0
- tunacode/ui/keybindings.py +7 -39
- tunacode/ui/output.py +39 -4
- tunacode/ui/panels.py +56 -2
- tunacode/ui/tool_descriptions.py +115 -0
- {tunacode_cli-0.0.53.dist-info → tunacode_cli-0.0.55.dist-info}/METADATA +1 -1
- {tunacode_cli-0.0.53.dist-info → tunacode_cli-0.0.55.dist-info}/RECORD +24 -21
- {tunacode_cli-0.0.53.dist-info → tunacode_cli-0.0.55.dist-info}/WHEEL +0 -0
- {tunacode_cli-0.0.53.dist-info → tunacode_cli-0.0.55.dist-info}/entry_points.txt +0 -0
- {tunacode_cli-0.0.53.dist-info → tunacode_cli-0.0.55.dist-info}/licenses/LICENSE +0 -0
- {tunacode_cli-0.0.53.dist-info → tunacode_cli-0.0.55.dist-info}/top_level.txt +0 -0
tunacode/ui/keybindings.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"""Key binding handlers for TunaCode UI."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
import time
|
|
5
4
|
|
|
6
|
-
from prompt_toolkit.application import run_in_terminal
|
|
7
5
|
from prompt_toolkit.key_binding import KeyBindings
|
|
8
6
|
|
|
9
7
|
from ..core.state import StateManager
|
|
@@ -32,38 +30,12 @@ def create_key_bindings(state_manager: StateManager = None) -> KeyBindings:
|
|
|
32
30
|
|
|
33
31
|
@kb.add("escape")
|
|
34
32
|
def _escape(event):
|
|
35
|
-
"""Handle ESC key
|
|
36
|
-
|
|
37
|
-
logger.debug("Escape key pressed without state manager")
|
|
38
|
-
return
|
|
33
|
+
"""Handle ESC key - raises KeyboardInterrupt for unified abort handling."""
|
|
34
|
+
logger.debug("ESC key pressed - raising KeyboardInterrupt")
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
# Reset counter if too much time has passed (3 seconds timeout)
|
|
44
|
-
if session.last_esc_time and (current_time - session.last_esc_time) > 3.0:
|
|
45
|
-
session.esc_press_count = 0
|
|
46
|
-
|
|
47
|
-
session.esc_press_count = (session.esc_press_count or 0) + 1
|
|
48
|
-
session.last_esc_time = current_time
|
|
49
|
-
|
|
50
|
-
logger.debug(f"ESC key pressed: count={session.esc_press_count}, time={current_time}")
|
|
51
|
-
|
|
52
|
-
if session.esc_press_count == 1:
|
|
53
|
-
# First ESC press - show warning message
|
|
54
|
-
from ..ui.output import warning
|
|
55
|
-
|
|
56
|
-
run_in_terminal(lambda: warning("Hit ESC again within 3 seconds to cancel operation"))
|
|
57
|
-
logger.debug("First ESC press - showing warning")
|
|
58
|
-
else:
|
|
59
|
-
# Second ESC press - cancel operation
|
|
60
|
-
session.esc_press_count = 0 # Reset counter
|
|
61
|
-
logger.debug("Second ESC press - initiating cancellation")
|
|
62
|
-
|
|
63
|
-
# Mark the session as being cancelled to prevent new operations
|
|
64
|
-
session.operation_cancelled = True
|
|
65
|
-
|
|
66
|
-
current_task = session.current_task
|
|
36
|
+
# Cancel any active task if present
|
|
37
|
+
if state_manager and hasattr(state_manager.session, "current_task"):
|
|
38
|
+
current_task = state_manager.session.current_task
|
|
67
39
|
if current_task and not current_task.done():
|
|
68
40
|
logger.debug(f"Cancelling current task: {current_task}")
|
|
69
41
|
try:
|
|
@@ -71,12 +43,8 @@ def create_key_bindings(state_manager: StateManager = None) -> KeyBindings:
|
|
|
71
43
|
logger.debug("Task cancellation initiated successfully")
|
|
72
44
|
except Exception as e:
|
|
73
45
|
logger.debug(f"Failed to cancel task: {e}")
|
|
74
|
-
else:
|
|
75
|
-
logger.debug(f"No active task to cancel: current_task={current_task}")
|
|
76
46
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
logger.debug("Raising KeyboardInterrupt to abort current operation")
|
|
80
|
-
raise KeyboardInterrupt()
|
|
47
|
+
# Raise KeyboardInterrupt to trigger unified abort handling in REPL
|
|
48
|
+
raise KeyboardInterrupt()
|
|
81
49
|
|
|
82
50
|
return kb
|
tunacode/ui/output.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Output and display functions for TunaCode UI."""
|
|
2
2
|
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
3
5
|
from prompt_toolkit.application import run_in_terminal
|
|
4
6
|
from rich.console import Console
|
|
5
7
|
from rich.padding import Padding
|
|
@@ -109,20 +111,39 @@ async def show_update_message(latest_version: str) -> None:
|
|
|
109
111
|
await update_available(latest_version)
|
|
110
112
|
|
|
111
113
|
|
|
112
|
-
async def spinner(
|
|
113
|
-
|
|
114
|
+
async def spinner(
|
|
115
|
+
show: bool = True,
|
|
116
|
+
spinner_obj=None,
|
|
117
|
+
state_manager: StateManager = None,
|
|
118
|
+
message: Optional[str] = None,
|
|
119
|
+
):
|
|
120
|
+
"""Manage a spinner display with dynamic message support.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
show: Whether to show (True) or hide (False) the spinner
|
|
124
|
+
spinner_obj: Existing spinner object to reuse
|
|
125
|
+
state_manager: State manager instance for storing spinner
|
|
126
|
+
message: Optional custom message to display (uses UI_THINKING_MESSAGE if None)
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
The spinner object for further manipulation
|
|
130
|
+
"""
|
|
114
131
|
icon = SPINNER_TYPE
|
|
115
|
-
|
|
132
|
+
display_message = message or UI_THINKING_MESSAGE
|
|
116
133
|
|
|
117
134
|
# Get spinner from state manager if available
|
|
118
135
|
if spinner_obj is None and state_manager:
|
|
119
136
|
spinner_obj = state_manager.session.spinner
|
|
120
137
|
|
|
121
138
|
if not spinner_obj:
|
|
122
|
-
spinner_obj = await run_in_terminal(lambda: console.status(
|
|
139
|
+
spinner_obj = await run_in_terminal(lambda: console.status(display_message, spinner=icon))
|
|
123
140
|
# Store it back in state manager if available
|
|
124
141
|
if state_manager:
|
|
125
142
|
state_manager.session.spinner = spinner_obj
|
|
143
|
+
else:
|
|
144
|
+
# Update existing spinner message if provided
|
|
145
|
+
if message and hasattr(spinner_obj, "update"):
|
|
146
|
+
spinner_obj.update(display_message)
|
|
126
147
|
|
|
127
148
|
if show:
|
|
128
149
|
spinner_obj.start()
|
|
@@ -132,6 +153,20 @@ async def spinner(show: bool = True, spinner_obj=None, state_manager: StateManag
|
|
|
132
153
|
return spinner_obj
|
|
133
154
|
|
|
134
155
|
|
|
156
|
+
async def update_spinner_message(message: str, state_manager: StateManager = None):
|
|
157
|
+
"""Update the spinner message if a spinner is active.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
message: New message to display
|
|
161
|
+
state_manager: State manager instance containing spinner
|
|
162
|
+
"""
|
|
163
|
+
if state_manager and state_manager.session.spinner:
|
|
164
|
+
spinner_obj = state_manager.session.spinner
|
|
165
|
+
if hasattr(spinner_obj, "update"):
|
|
166
|
+
# Rich's Status object supports update method
|
|
167
|
+
await run_in_terminal(lambda: spinner_obj.update(message))
|
|
168
|
+
|
|
169
|
+
|
|
135
170
|
def get_context_window_display(total_tokens: int, max_tokens: int) -> str:
|
|
136
171
|
"""
|
|
137
172
|
Create a color-coded display for the context window status.
|
tunacode/ui/panels.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Panel display functions for TunaCode UI."""
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
4
|
+
import time
|
|
3
5
|
from typing import Any, Optional, Union
|
|
4
6
|
|
|
5
7
|
from rich.box import ROUNDED
|
|
@@ -81,11 +83,24 @@ async def agent(text: str, bottom: int = 1) -> None:
|
|
|
81
83
|
class StreamingAgentPanel:
|
|
82
84
|
"""Streaming agent panel using Rich.Live for progressive display."""
|
|
83
85
|
|
|
86
|
+
bottom: int
|
|
87
|
+
title: str
|
|
88
|
+
content: str
|
|
89
|
+
live: Optional[Live]
|
|
90
|
+
_last_update_time: float
|
|
91
|
+
_dots_task: Optional[asyncio.Task]
|
|
92
|
+
_dots_count: int
|
|
93
|
+
_show_dots: bool
|
|
94
|
+
|
|
84
95
|
def __init__(self, bottom: int = 1):
|
|
85
96
|
self.bottom = bottom
|
|
86
97
|
self.title = f"[bold {colors.primary}]●[/bold {colors.primary}] {APP_NAME}"
|
|
87
98
|
self.content = ""
|
|
88
99
|
self.live = None
|
|
100
|
+
self._last_update_time = 0.0
|
|
101
|
+
self._dots_task = None
|
|
102
|
+
self._dots_count = 0
|
|
103
|
+
self._show_dots = False
|
|
89
104
|
|
|
90
105
|
def _create_panel(self) -> Padding:
|
|
91
106
|
"""Create a Rich panel with current content."""
|
|
@@ -94,11 +109,19 @@ class StreamingAgentPanel:
|
|
|
94
109
|
|
|
95
110
|
from tunacode.constants import UI_THINKING_MESSAGE
|
|
96
111
|
|
|
97
|
-
#
|
|
112
|
+
# Show "Thinking..." only when no content has arrived yet
|
|
98
113
|
if not self.content:
|
|
99
114
|
content_renderable: Union[Text, Markdown] = Text.from_markup(UI_THINKING_MESSAGE)
|
|
100
115
|
else:
|
|
101
|
-
|
|
116
|
+
# Once we have content, show it with optional dots animation
|
|
117
|
+
display_content = self.content
|
|
118
|
+
# Add animated dots if we're waiting for more content
|
|
119
|
+
if self._show_dots:
|
|
120
|
+
# Cycle through: "", ".", "..", "..."
|
|
121
|
+
dots_patterns = ["", ".", "..", "..."]
|
|
122
|
+
dots = dots_patterns[self._dots_count % len(dots_patterns)]
|
|
123
|
+
display_content = self.content.rstrip() + dots
|
|
124
|
+
content_renderable = Markdown(display_content)
|
|
102
125
|
panel_obj = Panel(
|
|
103
126
|
Padding(content_renderable, (0, 1, 0, 1)),
|
|
104
127
|
title=f"[bold]{self.title}[/bold]",
|
|
@@ -117,12 +140,30 @@ class StreamingAgentPanel:
|
|
|
117
140
|
),
|
|
118
141
|
)
|
|
119
142
|
|
|
143
|
+
async def _animate_dots(self):
|
|
144
|
+
"""Animate dots after a pause in streaming."""
|
|
145
|
+
while True:
|
|
146
|
+
await asyncio.sleep(0.5)
|
|
147
|
+
current_time = time.time()
|
|
148
|
+
# Only show dots after 1 second of no updates
|
|
149
|
+
if current_time - self._last_update_time > 1.0:
|
|
150
|
+
self._show_dots = True
|
|
151
|
+
self._dots_count += 1
|
|
152
|
+
if self.live:
|
|
153
|
+
self.live.update(self._create_panel())
|
|
154
|
+
else:
|
|
155
|
+
self._show_dots = False
|
|
156
|
+
self._dots_count = 0
|
|
157
|
+
|
|
120
158
|
async def start(self):
|
|
121
159
|
"""Start the live streaming display."""
|
|
122
160
|
from .output import console
|
|
123
161
|
|
|
124
162
|
self.live = Live(self._create_panel(), console=console, refresh_per_second=4)
|
|
125
163
|
self.live.start()
|
|
164
|
+
self._last_update_time = time.time()
|
|
165
|
+
# Start the dots animation task
|
|
166
|
+
self._dots_task = asyncio.create_task(self._animate_dots())
|
|
126
167
|
|
|
127
168
|
async def update(self, content_chunk: str):
|
|
128
169
|
"""Update the streaming display with new content."""
|
|
@@ -131,6 +172,11 @@ class StreamingAgentPanel:
|
|
|
131
172
|
content_chunk = ""
|
|
132
173
|
# Ensure type safety for concatenation
|
|
133
174
|
self.content = (self.content or "") + str(content_chunk)
|
|
175
|
+
|
|
176
|
+
# Reset the update timer when we get new content
|
|
177
|
+
self._last_update_time = time.time()
|
|
178
|
+
self._show_dots = False # Hide dots immediately when new content arrives
|
|
179
|
+
|
|
134
180
|
if self.live:
|
|
135
181
|
self.live.update(self._create_panel())
|
|
136
182
|
|
|
@@ -142,6 +188,14 @@ class StreamingAgentPanel:
|
|
|
142
188
|
|
|
143
189
|
async def stop(self):
|
|
144
190
|
"""Stop the live streaming display."""
|
|
191
|
+
# Cancel the dots animation task
|
|
192
|
+
if self._dots_task:
|
|
193
|
+
self._dots_task.cancel()
|
|
194
|
+
try:
|
|
195
|
+
await self._dots_task
|
|
196
|
+
except asyncio.CancelledError:
|
|
197
|
+
pass
|
|
198
|
+
|
|
145
199
|
if self.live:
|
|
146
200
|
# Get the console before stopping the live display
|
|
147
201
|
from .output import console
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Tool description mappings for user-friendly spinner messages."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_tool_description(tool_name: str, args: Optional[Dict] = None) -> str:
|
|
7
|
+
"""
|
|
8
|
+
Get a human-readable description for a tool execution.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
tool_name: Name of the tool being executed
|
|
12
|
+
args: Optional tool arguments for more specific descriptions
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
User-friendly description of the tool operation
|
|
16
|
+
"""
|
|
17
|
+
# Base descriptions for each tool
|
|
18
|
+
base_descriptions = {
|
|
19
|
+
# File operations
|
|
20
|
+
"read_file": "Reading file",
|
|
21
|
+
"write_file": "Writing file",
|
|
22
|
+
"update_file": "Updating file",
|
|
23
|
+
"create_file": "Creating file",
|
|
24
|
+
"delete_file": "Deleting file",
|
|
25
|
+
# Directory operations
|
|
26
|
+
"list_dir": "Listing directory",
|
|
27
|
+
"create_dir": "Creating directory",
|
|
28
|
+
"delete_dir": "Deleting directory",
|
|
29
|
+
# Search operations
|
|
30
|
+
"grep": "Searching files",
|
|
31
|
+
"glob": "Finding files",
|
|
32
|
+
"find_files": "Searching for files",
|
|
33
|
+
# Code operations
|
|
34
|
+
"run_command": "Executing command",
|
|
35
|
+
"bash": "Running shell command",
|
|
36
|
+
"python": "Executing Python code",
|
|
37
|
+
# Analysis operations
|
|
38
|
+
"analyze_code": "Analyzing code",
|
|
39
|
+
"lint": "Running linter",
|
|
40
|
+
"format_code": "Formatting code",
|
|
41
|
+
# Version control
|
|
42
|
+
"git_status": "Checking git status",
|
|
43
|
+
"git_diff": "Getting git diff",
|
|
44
|
+
"git_commit": "Creating git commit",
|
|
45
|
+
# Testing
|
|
46
|
+
"run_tests": "Running tests",
|
|
47
|
+
"test": "Executing tests",
|
|
48
|
+
# Documentation
|
|
49
|
+
"generate_docs": "Generating documentation",
|
|
50
|
+
"update_docs": "Updating documentation",
|
|
51
|
+
# Default
|
|
52
|
+
"unknown": "Processing",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Get base description
|
|
56
|
+
base_desc = base_descriptions.get(tool_name, f"Executing {tool_name}")
|
|
57
|
+
|
|
58
|
+
# Add specific details from args if available
|
|
59
|
+
if args:
|
|
60
|
+
if tool_name == "read_file" and "file_path" in args:
|
|
61
|
+
return f"{base_desc}: {args['file_path']}"
|
|
62
|
+
elif tool_name == "write_file" and "file_path" in args:
|
|
63
|
+
return f"{base_desc}: {args['file_path']}"
|
|
64
|
+
elif tool_name == "update_file" and "file_path" in args:
|
|
65
|
+
return f"{base_desc}: {args['file_path']}"
|
|
66
|
+
elif tool_name == "list_dir" and "directory" in args:
|
|
67
|
+
return f"{base_desc}: {args['directory']}"
|
|
68
|
+
elif tool_name == "grep" and "pattern" in args:
|
|
69
|
+
pattern = args["pattern"]
|
|
70
|
+
# Truncate long patterns
|
|
71
|
+
if len(pattern) > 30:
|
|
72
|
+
pattern = pattern[:27] + "..."
|
|
73
|
+
return f"{base_desc} for: {pattern}"
|
|
74
|
+
elif tool_name == "glob" and "pattern" in args:
|
|
75
|
+
return f"{base_desc}: {args['pattern']}"
|
|
76
|
+
elif tool_name == "run_command" and "command" in args:
|
|
77
|
+
cmd = args["command"]
|
|
78
|
+
# Truncate long commands
|
|
79
|
+
if len(cmd) > 40:
|
|
80
|
+
cmd = cmd[:37] + "..."
|
|
81
|
+
return f"{base_desc}: {cmd}"
|
|
82
|
+
elif tool_name == "bash" and "command" in args:
|
|
83
|
+
cmd = args["command"]
|
|
84
|
+
if len(cmd) > 40:
|
|
85
|
+
cmd = cmd[:37] + "..."
|
|
86
|
+
return f"{base_desc}: {cmd}"
|
|
87
|
+
|
|
88
|
+
return base_desc
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_batch_description(tool_count: int, tool_names: Optional[list] = None) -> str:
|
|
92
|
+
"""
|
|
93
|
+
Get a description for batch tool execution.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
tool_count: Number of tools being executed
|
|
97
|
+
tool_names: Optional list of tool names for more detail
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Description of the batch operation
|
|
101
|
+
"""
|
|
102
|
+
if tool_count == 1:
|
|
103
|
+
return "Executing 1 tool"
|
|
104
|
+
|
|
105
|
+
if tool_names and len(set(tool_names)) == 1:
|
|
106
|
+
# All tools are the same type
|
|
107
|
+
tool_type = tool_names[0]
|
|
108
|
+
if tool_type == "read_file":
|
|
109
|
+
return f"Reading {tool_count} files in parallel"
|
|
110
|
+
elif tool_type == "grep":
|
|
111
|
+
return f"Searching {tool_count} patterns in parallel"
|
|
112
|
+
elif tool_type == "list_dir":
|
|
113
|
+
return f"Listing {tool_count} directories in parallel"
|
|
114
|
+
|
|
115
|
+
return f"Executing {tool_count} tools in parallel"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
tunacode/__init__.py,sha256=yUul8igNYMfUrHnYfioIGAqvrH8b5BKiO_pt1wVnmd0,119
|
|
2
|
-
tunacode/constants.py,sha256=
|
|
2
|
+
tunacode/constants.py,sha256=nNS_4fOgxWjzUxnCm-FBXgfVRifwFytkt7yICn7eL1I,5968
|
|
3
3
|
tunacode/context.py,sha256=YtfRjUiqsSkk2k9Nn_pjb_m-AXyh6XcOBOJWtFI0wVw,2405
|
|
4
4
|
tunacode/exceptions.py,sha256=oDO1SVKOgjcKIylwqdbqh_g5my4roU5mB9Nv4n_Vb0s,3877
|
|
5
5
|
tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -7,10 +7,10 @@ tunacode/setup.py,sha256=a5S-uGkVYoBTvH9nsqMBgAFoH4CILOgfKvgS30qGnoU,1978
|
|
|
7
7
|
tunacode/types.py,sha256=bCJ0mq1iQKa42fhBN5Pimkx0FV0f2J3-qRzbMzFhmBw,8499
|
|
8
8
|
tunacode/cli/__init__.py,sha256=zgs0UbAck8hfvhYsWhWOfBe5oK09ug2De1r4RuQZREA,55
|
|
9
9
|
tunacode/cli/main.py,sha256=4MF4nGEU-CB83ckIl85AY-015EeUJHrE_UdbuSa9wCU,2968
|
|
10
|
-
tunacode/cli/repl.py,sha256=
|
|
11
|
-
tunacode/cli/commands/__init__.py,sha256=
|
|
10
|
+
tunacode/cli/repl.py,sha256=GMEvDW8LP1iM-bwOY83BviYk0fMngDJiZiI3f28CHwo,16327
|
|
11
|
+
tunacode/cli/commands/__init__.py,sha256=7rPwGkdYbPUgf__cPVX9oQUJOPQ18MdxDT_I64crdak,1740
|
|
12
12
|
tunacode/cli/commands/base.py,sha256=Ge_lNQA-GDfcb1Ap1oznCH3UrifBiHH3bA9DNL-tCDw,2519
|
|
13
|
-
tunacode/cli/commands/registry.py,sha256=
|
|
13
|
+
tunacode/cli/commands/registry.py,sha256=Xmfb4qRZ1wvT-3OggGsuDxpXlCykuhOkSBberysj1SE,9345
|
|
14
14
|
tunacode/cli/commands/template_shortcut.py,sha256=ApYTPkDVBRaLxa7rWaPrsGcJdkR7eg09k18KyTjYg_E,3447
|
|
15
15
|
tunacode/cli/commands/implementations/__init__.py,sha256=DHjQm1f14OV1go0ZyqacFa3yfnGWH7LZFbZVVQZ5Iw0,1011
|
|
16
16
|
tunacode/cli/commands/implementations/conversation.py,sha256=ZijCNaRi1p5v1Q-IaVHtU2_BripSW3JCVKTtqFkOUjg,4676
|
|
@@ -24,28 +24,30 @@ tunacode/cli/repl_components/__init__.py,sha256=5ZjPJ3yUvZ5x6Vg9EYJ03-tdxfEEdmfr
|
|
|
24
24
|
tunacode/cli/repl_components/command_parser.py,sha256=SuDRP-nt8Sq5klI4-tXkllN_4nVzji5VJ-dQvbxDmDw,880
|
|
25
25
|
tunacode/cli/repl_components/error_recovery.py,sha256=yPoWXzuMi6B_Pwlm1wnFIJV55lJEOChvHGDca4XtoVI,3064
|
|
26
26
|
tunacode/cli/repl_components/output_display.py,sha256=SGhP7Hc1ymfZf-AvrkELgdJCZ3UVEzTx2Y6W737zdoY,816
|
|
27
|
-
tunacode/cli/repl_components/tool_executor.py,sha256=
|
|
27
|
+
tunacode/cli/repl_components/tool_executor.py,sha256=p5oSpoO0qkiKr9fsgIQVSXCv6ZiSWk8QtPb_x7IpKhE,3147
|
|
28
28
|
tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
|
|
29
29
|
tunacode/configuration/defaults.py,sha256=5TUeSqMTeA7kW7gz9hND_H4s9Key0_khPvc6mNFMlZc,838
|
|
30
30
|
tunacode/configuration/models.py,sha256=buH8ZquvcYI3OQBDIZeJ08cu00rSCeNABtUwl3VQS0E,4103
|
|
31
31
|
tunacode/configuration/settings.py,sha256=9wtIWBlLhW_ZBlLx-GA4XDfVZyGj2Gs6Zk49vk-nHq0,1047
|
|
32
32
|
tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
33
|
tunacode/core/code_index.py,sha256=jgAx3lSWP_DwnyiP5Jkm1YvX4JJyI4teMzlNrJSpEOA,15661
|
|
34
|
-
tunacode/core/state.py,sha256=
|
|
34
|
+
tunacode/core/state.py,sha256=RGBTOHTpe4z42MbIjRKhGNz9MIGyY0QbpdDJMldm53o,6284
|
|
35
35
|
tunacode/core/tool_handler.py,sha256=FqA3w8M_fhpyOQKJIgl_8MAhSFVEguufbZH6gm_b7NI,2932
|
|
36
36
|
tunacode/core/agents/__init__.py,sha256=UUJiPYb91arwziSpjd7vIk7XNGA_4HQbsOIbskSqevA,149
|
|
37
|
-
tunacode/core/agents/main.py,sha256=
|
|
37
|
+
tunacode/core/agents/main.py,sha256=myz_K2lxqYH8pQdbw8n8bai8F40Mqfj-kTLagPR1dP4,18253
|
|
38
38
|
tunacode/core/agents/utils.py,sha256=dJsdbvWs48vxQpwAtUjJLMj7_huv12Mx3E2CEgwoK94,14467
|
|
39
|
-
tunacode/core/agents/agent_components/__init__.py,sha256=
|
|
39
|
+
tunacode/core/agents/agent_components/__init__.py,sha256=CL4XH47T6v_iYy7xCPYjyiEFNOFnkcKwbTuKw6IjKTs,1474
|
|
40
40
|
tunacode/core/agents/agent_components/agent_config.py,sha256=6m2RBZ7Y-0p_KFBVmfPW4ZGLGzTAw3YFQ4i94qsqEpM,4373
|
|
41
|
+
tunacode/core/agents/agent_components/agent_helpers.py,sha256=G3zF5GPRzBhA3yOcsXf8gar892ackGDcwFk9wM6FA9s,8119
|
|
41
42
|
tunacode/core/agents/agent_components/json_tool_parser.py,sha256=HuyNT0rs-ppx_gLAI2e0XMVGbR_F0WXZfP3sx38VoMg,3447
|
|
42
43
|
tunacode/core/agents/agent_components/message_handler.py,sha256=KJGOtb9VhumgZpxxwO45HrKLhU9_MwuoWRsSQwJviNU,3704
|
|
43
|
-
tunacode/core/agents/agent_components/node_processor.py,sha256=
|
|
44
|
+
tunacode/core/agents/agent_components/node_processor.py,sha256=FmjIEJWkqc0uzRfgTINv8uJwKG7-w00mV5lgOS4Jcd8,20426
|
|
44
45
|
tunacode/core/agents/agent_components/response_state.py,sha256=_C2loLeyZHMFHwjGny4h0dI02UoFJcJAVaabkh9H9JQ,343
|
|
45
46
|
tunacode/core/agents/agent_components/result_wrapper.py,sha256=9CFK0wpsfZx2WT4PBHfkSv22GxL1gAQuUYVMlmYtCJU,1761
|
|
46
47
|
tunacode/core/agents/agent_components/task_completion.py,sha256=BSnjNEFbxlzgzcXdjdTVGeCr1RpCiAaEp_D7f5FXa5Q,819
|
|
47
48
|
tunacode/core/agents/agent_components/tool_buffer.py,sha256=09FNtC6zTjiJOL_2CY0b7KDgwdNayGPV6jbENKH6Unc,766
|
|
48
49
|
tunacode/core/agents/agent_components/tool_executor.py,sha256=LlzDwgSLLawwPZQqJ4vfLf-16nhwIiuN8zm8iCeBf1Y,1849
|
|
50
|
+
tunacode/core/agents/agent_components/truncation_checker.py,sha256=XbJ3wwtdC4NhgIMIvFR0z_cfNnYMkiYAZo9zGDBPU8Y,2685
|
|
49
51
|
tunacode/core/background/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
52
|
tunacode/core/background/manager.py,sha256=AxNcuuE7T2pqeI2lLIGJgaS_jEw60YzBfZY9EOY54fc,1160
|
|
51
53
|
tunacode/core/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -65,7 +67,7 @@ tunacode/core/setup/template_setup.py,sha256=0lDGhNVCvGN7ykqHnl3pj4CONH3I2PvMzkm
|
|
|
65
67
|
tunacode/core/token_usage/api_response_parser.py,sha256=plLltHg4zGVzxjv3MFj45bbd-NOJeT_v3P0Ki4zlvn4,1831
|
|
66
68
|
tunacode/core/token_usage/cost_calculator.py,sha256=RjO-O0JENBuGOrWP7QgBZlZxeXC-PAIr8tj_9p_BxOU,2058
|
|
67
69
|
tunacode/core/token_usage/usage_tracker.py,sha256=G6lt9VXnS3JcXsiPTwuS3v1YptI_7gfV78f08jX22yU,5932
|
|
68
|
-
tunacode/prompts/system.md,sha256=
|
|
70
|
+
tunacode/prompts/system.md,sha256=jrPtKFLu2CD6WpNNFgN1nc0p3mec4En9VYmpRQxyZi8,24080
|
|
69
71
|
tunacode/services/__init__.py,sha256=w_E8QK6RnvKSvU866eDe8BCRV26rAm4d3R-Yg06OWCU,19
|
|
70
72
|
tunacode/services/mcp.py,sha256=R48X73KQjQ9vwhBrtbWHSBl-4K99QXmbIhh5J_1Gezo,3046
|
|
71
73
|
tunacode/templates/__init__.py,sha256=ssEOPrPjyCywtKI-QFcoqcWhMjlfI5TbI8Ip0_wyqGM,241
|
|
@@ -74,7 +76,7 @@ tunacode/tools/__init__.py,sha256=ECBuUWWF1JjHW42CCceaPKgVTQyuljbz3RlhuA2fe2s,31
|
|
|
74
76
|
tunacode/tools/base.py,sha256=DhlanZZZxU2JJaBOwwyGFKMUcoCWR_CzLuwVeSXC0Go,7297
|
|
75
77
|
tunacode/tools/bash.py,sha256=mgZqugfDFevZ4BETuUv90pzXvtq7qKGUGFiuDxzmytk,8766
|
|
76
78
|
tunacode/tools/glob.py,sha256=mQwVGC8dfvzwzUOeTikfnHhExnLcYnGQwDoHOWrt_fE,10342
|
|
77
|
-
tunacode/tools/grep.py,sha256=
|
|
79
|
+
tunacode/tools/grep.py,sha256=SfpLazOMbizganPO16w7v6iHRcUn0cD6-6lyUwrl-3U,17834
|
|
78
80
|
tunacode/tools/list_dir.py,sha256=1kNqzYCNlcA5rqXIEVqcjQy6QxlLZLj5AG6YIECfwio,7217
|
|
79
81
|
tunacode/tools/read_file.py,sha256=z2omev9xzj4-0GG9mRssD13rj-Aa1c-pszFi2Z7Hxvk,3268
|
|
80
82
|
tunacode/tools/read_file_async_poc.py,sha256=2v2ckLQlwahgPGWGdE2c5Es37B35Y7zWdseZwT46E1E,6453
|
|
@@ -89,16 +91,17 @@ tunacode/tools/grep_components/result_formatter.py,sha256=aa0tJitbG9IalWYWKG0nIn
|
|
|
89
91
|
tunacode/tools/grep_components/search_result.py,sha256=xzb_htSANuPIPVWViPAqIMsCCWVA8loxWdaZOA8RqMs,869
|
|
90
92
|
tunacode/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
|
|
91
93
|
tunacode/ui/completers.py,sha256=18f1Im5210-b-qNKyCoOMnSjW99FXNoF0DtgRvEWTm0,4901
|
|
92
|
-
tunacode/ui/console.py,sha256=
|
|
94
|
+
tunacode/ui/console.py,sha256=HfE30vUy8ebXCobP7psFNJc17-dvH6APChg2tbi7aTw,2632
|
|
93
95
|
tunacode/ui/constants.py,sha256=A76B_KpM8jCuBYRg4cPmhi8_j6LLyWttO7_jjv47r3w,421
|
|
94
96
|
tunacode/ui/decorators.py,sha256=jJDNztO8MyX_IG1nqXAL8-sQUFjaAzBnc5BsM3ioX24,1955
|
|
95
97
|
tunacode/ui/input.py,sha256=NCZlj5qzNPy0gsSeGKeDNdAOMKZVGph8Z-UBXhX-Sbk,3020
|
|
96
|
-
tunacode/ui/keybindings.py,sha256=
|
|
98
|
+
tunacode/ui/keybindings.py,sha256=YUyi6I0xXs9mNjT0qnKh_SXsfSYb6eNUD44pV_q5TVI,1685
|
|
97
99
|
tunacode/ui/lexers.py,sha256=tmg4ic1enyTRLzanN5QPP7D_0n12YjX_8ZhsffzhXA4,1340
|
|
98
100
|
tunacode/ui/logging_compat.py,sha256=5v6lcjVaG1CxdY1Zm9FAGr9H7Sy-tP6ihGfhP-5YvAY,1406
|
|
99
|
-
tunacode/ui/output.py,sha256=
|
|
100
|
-
tunacode/ui/panels.py,sha256=
|
|
101
|
+
tunacode/ui/output.py,sha256=C2LHKAZxBySsIfk9saJ-jZrsZBE7f3WeP-RHpn5TChQ,6808
|
|
102
|
+
tunacode/ui/panels.py,sha256=wccIQ-exLs5oBedFZRU1lsY69fRqf-em_5gTTRM0Luc,11527
|
|
101
103
|
tunacode/ui/prompt_manager.py,sha256=489r-WtuR3gdaugEr1lSV7SvtmXF2IlhDQckvzjYG2c,4676
|
|
104
|
+
tunacode/ui/tool_descriptions.py,sha256=vk61JPIXy7gHNfJ--77maXgK6WwNwxqY47QYsw_a2uw,4126
|
|
102
105
|
tunacode/ui/tool_ui.py,sha256=bLydo5Y42b2gbUMP2kM6m_stIkj4Q1wbwaqO-1P6O1g,7198
|
|
103
106
|
tunacode/ui/utils.py,sha256=yvoCTz8AOdRfV0XIqUX3sgg88g_wntV9yhnQP6WzAVs,114
|
|
104
107
|
tunacode/ui/validators.py,sha256=MMIMT1I2v0l2jIy-gxX_4GSApvUTi8XWIOACr_dmoBA,758
|
|
@@ -115,9 +118,9 @@ tunacode/utils/system.py,sha256=J8KqJ4ZqQrNSnM5rrJxPeMk9z2xQQp6dWtI1SKBY1-0,1112
|
|
|
115
118
|
tunacode/utils/text_utils.py,sha256=HAwlT4QMy41hr53cDbbNeNo05MI461TpI9b_xdIv8EY,7288
|
|
116
119
|
tunacode/utils/token_counter.py,sha256=dmFuqVz4ywGFdLfAi5Mg9bAGf8v87Ek-mHU-R3fsYjI,2711
|
|
117
120
|
tunacode/utils/user_configuration.py,sha256=Ilz8dpGVJDBE2iLWHAPT0xR8D51VRKV3kIbsAz8Bboc,3275
|
|
118
|
-
tunacode_cli-0.0.
|
|
119
|
-
tunacode_cli-0.0.
|
|
120
|
-
tunacode_cli-0.0.
|
|
121
|
-
tunacode_cli-0.0.
|
|
122
|
-
tunacode_cli-0.0.
|
|
123
|
-
tunacode_cli-0.0.
|
|
121
|
+
tunacode_cli-0.0.55.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
|
|
122
|
+
tunacode_cli-0.0.55.dist-info/METADATA,sha256=nB8M3oUVfbFFUBxldQFl86PjnnuxhhL6KGeal1iE88g,10193
|
|
123
|
+
tunacode_cli-0.0.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
124
|
+
tunacode_cli-0.0.55.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
|
|
125
|
+
tunacode_cli-0.0.55.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
|
|
126
|
+
tunacode_cli-0.0.55.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|