tunacode-cli 0.0.29__py3-none-any.whl → 0.0.31__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.
- api/auth.py +13 -0
- api/users.py +8 -0
- tunacode/cli/commands.py +115 -233
- tunacode/cli/repl.py +53 -63
- tunacode/cli/textual_bridge.py +4 -1
- tunacode/constants.py +10 -1
- tunacode/core/agents/__init__.py +0 -4
- tunacode/core/agents/main.py +454 -49
- tunacode/core/code_index.py +479 -0
- tunacode/core/setup/git_safety_setup.py +7 -9
- tunacode/core/state.py +5 -0
- tunacode/core/tool_handler.py +18 -0
- tunacode/exceptions.py +13 -0
- tunacode/prompts/system.md +269 -30
- tunacode/tools/glob.py +288 -0
- tunacode/tools/grep.py +168 -195
- tunacode/tools/list_dir.py +190 -0
- tunacode/tools/read_file.py +9 -3
- tunacode/tools/read_file_async_poc.py +188 -0
- tunacode/utils/text_utils.py +14 -5
- tunacode/utils/token_counter.py +23 -0
- {tunacode_cli-0.0.29.dist-info → tunacode_cli-0.0.31.dist-info}/METADATA +16 -7
- {tunacode_cli-0.0.29.dist-info → tunacode_cli-0.0.31.dist-info}/RECORD +27 -24
- {tunacode_cli-0.0.29.dist-info → tunacode_cli-0.0.31.dist-info}/top_level.txt +1 -0
- tunacode/core/agents/orchestrator.py +0 -213
- tunacode/core/agents/planner_schema.py +0 -9
- tunacode/core/agents/readonly.py +0 -65
- tunacode/core/llm/planner.py +0 -62
- {tunacode_cli-0.0.29.dist-info → tunacode_cli-0.0.31.dist-info}/WHEEL +0 -0
- {tunacode_cli-0.0.29.dist-info → tunacode_cli-0.0.31.dist-info}/entry_points.txt +0 -0
- {tunacode_cli-0.0.29.dist-info → tunacode_cli-0.0.31.dist-info}/licenses/LICENSE +0 -0
tunacode/core/agents/readonly.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"""Read-only agent implementation for non-mutating operations."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
6
|
-
|
|
7
|
-
from ...tools.grep import grep
|
|
8
|
-
from ...tools.read_file import read_file
|
|
9
|
-
from ...types import AgentRun, ModelName, ResponseState
|
|
10
|
-
from ..state import StateManager
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from ...types import PydanticAgent
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class ReadOnlyAgent:
|
|
17
|
-
"""Agent configured with read-only tools for analysis tasks."""
|
|
18
|
-
|
|
19
|
-
def __init__(self, model: ModelName, state_manager: StateManager):
|
|
20
|
-
self.model = model
|
|
21
|
-
self.state_manager = state_manager
|
|
22
|
-
self._agent: PydanticAgent | None = None
|
|
23
|
-
|
|
24
|
-
def _get_agent(self) -> PydanticAgent:
|
|
25
|
-
"""Lazily create the agent with read-only tools."""
|
|
26
|
-
if self._agent is None:
|
|
27
|
-
from .main import get_agent_tool
|
|
28
|
-
|
|
29
|
-
Agent, Tool = get_agent_tool()
|
|
30
|
-
|
|
31
|
-
# Create agent with only read-only tools
|
|
32
|
-
self._agent = Agent(
|
|
33
|
-
model=self.model,
|
|
34
|
-
system_prompt="You are a read-only assistant. You can analyze and read files but cannot modify them.",
|
|
35
|
-
tools=[
|
|
36
|
-
Tool(read_file),
|
|
37
|
-
Tool(grep),
|
|
38
|
-
],
|
|
39
|
-
)
|
|
40
|
-
return self._agent
|
|
41
|
-
|
|
42
|
-
async def process_request(self, request: str) -> AgentRun:
|
|
43
|
-
"""Process a request using only read-only tools."""
|
|
44
|
-
agent = self._get_agent()
|
|
45
|
-
response_state = ResponseState()
|
|
46
|
-
|
|
47
|
-
# Use iter() like main.py does to get the full run context
|
|
48
|
-
async with agent.iter(request) as agent_run:
|
|
49
|
-
async for node in agent_run:
|
|
50
|
-
# Check if this node produced user-visible output
|
|
51
|
-
if hasattr(node, "result") and node.result and hasattr(node.result, "output"):
|
|
52
|
-
if node.result.output:
|
|
53
|
-
response_state.has_user_response = True
|
|
54
|
-
|
|
55
|
-
# Wrap the agent run to include response_state
|
|
56
|
-
class AgentRunWithState:
|
|
57
|
-
def __init__(self, wrapped_run):
|
|
58
|
-
self._wrapped = wrapped_run
|
|
59
|
-
self.response_state = response_state
|
|
60
|
-
|
|
61
|
-
def __getattr__(self, name):
|
|
62
|
-
# Delegate all other attributes to the wrapped object
|
|
63
|
-
return getattr(self._wrapped, name)
|
|
64
|
-
|
|
65
|
-
return AgentRunWithState(agent_run)
|
tunacode/core/llm/planner.py
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
|
-
from ...types import ModelName
|
|
4
|
-
from ..agents.planner_schema import Task
|
|
5
|
-
from ..state import StateManager
|
|
6
|
-
|
|
7
|
-
_SYSTEM = """You are a senior software project planner.
|
|
8
|
-
|
|
9
|
-
Your job is to break down a USER_REQUEST into a logical sequence of tasks.
|
|
10
|
-
|
|
11
|
-
Guidelines:
|
|
12
|
-
1. Use the FEWEST tasks possible - combine related operations
|
|
13
|
-
2. Order tasks logically - reads before writes, understand before modify
|
|
14
|
-
3. Mark read-only tasks (reading files, searching, analyzing) as mutate: false
|
|
15
|
-
4. Mark modifying tasks (writing, updating, creating files) as mutate: true
|
|
16
|
-
5. Write clear, actionable descriptions
|
|
17
|
-
|
|
18
|
-
Each task MUST have:
|
|
19
|
-
- id: Sequential number starting from 1
|
|
20
|
-
- description: Clear description of what needs to be done
|
|
21
|
-
- mutate: true if the task modifies files/code, false if it only reads/analyzes
|
|
22
|
-
|
|
23
|
-
Return ONLY a valid JSON array of tasks, no other text.
|
|
24
|
-
Example:
|
|
25
|
-
[
|
|
26
|
-
{"id": 1, "description": "Read the main.py file to understand the structure", "mutate": false},
|
|
27
|
-
{"id": 2, "description": "Update the function to handle edge cases", "mutate": true}
|
|
28
|
-
]"""
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
async def make_plan(request: str, model: ModelName, state_manager: StateManager) -> List[Task]:
|
|
32
|
-
"""Generate an execution plan from a user request using TunaCode's LLM infrastructure."""
|
|
33
|
-
# Lazy import to avoid circular dependencies
|
|
34
|
-
from rich.console import Console
|
|
35
|
-
|
|
36
|
-
from ..agents.main import get_agent_tool
|
|
37
|
-
|
|
38
|
-
console = Console()
|
|
39
|
-
Agent, _ = get_agent_tool()
|
|
40
|
-
|
|
41
|
-
# Show planning is starting
|
|
42
|
-
console.print("\n[dim][Planning] Breaking down request into tasks...[/dim]")
|
|
43
|
-
|
|
44
|
-
# Create a simple planning agent
|
|
45
|
-
planner = Agent(
|
|
46
|
-
model=model,
|
|
47
|
-
system_prompt=_SYSTEM,
|
|
48
|
-
result_type=List[Task],
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# Get the plan from the agent
|
|
52
|
-
result = await planner.run(request)
|
|
53
|
-
tasks = result.data
|
|
54
|
-
|
|
55
|
-
# Display the plan
|
|
56
|
-
console.print(f"[dim][Planning] Generated {len(tasks)} tasks:[/dim]")
|
|
57
|
-
for task in tasks:
|
|
58
|
-
task_type = "WRITE" if task.mutate else "READ"
|
|
59
|
-
console.print(f"[dim] Task {task.id}: {task_type} - {task.description}[/dim]")
|
|
60
|
-
console.print("")
|
|
61
|
-
|
|
62
|
-
return tasks
|
|
File without changes
|
|
File without changes
|
|
File without changes
|