janito 0.7.0__py3-none-any.whl → 0.9.0__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.
- janito/__init__.py +5 -2
- janito/__main__.py +151 -142
- janito/callbacks.py +130 -0
- janito/cli.py +202 -0
- janito/config.py +57 -96
- janito/data/instructions.txt +6 -0
- janito/test_file.py +4 -0
- janito/token_report.py +73 -0
- janito/tools/__init__.py +10 -0
- janito/tools/decorators.py +84 -0
- janito/tools/delete_file.py +44 -0
- janito/tools/find_files.py +154 -0
- janito/tools/search_text.py +197 -0
- janito/tools/str_replace_editor/__init__.py +6 -0
- janito/tools/str_replace_editor/editor.py +43 -0
- janito/tools/str_replace_editor/handlers.py +338 -0
- janito/tools/str_replace_editor/utils.py +88 -0
- {janito-0.7.0.dist-info/licenses → janito-0.9.0.dist-info}/LICENSE +20 -20
- janito-0.9.0.dist-info/METADATA +9 -0
- janito-0.9.0.dist-info/RECORD +23 -0
- {janito-0.7.0.dist-info → janito-0.9.0.dist-info}/WHEEL +2 -1
- janito-0.9.0.dist-info/entry_points.txt +2 -0
- janito-0.9.0.dist-info/top_level.txt +1 -0
- janito/agents/__init__.py +0 -22
- janito/agents/agent.py +0 -28
- janito/agents/claudeai.py +0 -45
- janito/agents/openai.py +0 -57
- janito/agents/test.py +0 -34
- janito/change/__init__.py +0 -32
- janito/change/__main__.py +0 -0
- janito/change/analysis/__init__.py +0 -23
- janito/change/analysis/__main__.py +0 -7
- janito/change/analysis/analyze.py +0 -62
- janito/change/analysis/formatting.py +0 -78
- janito/change/analysis/options.py +0 -81
- janito/change/analysis/prompts.py +0 -90
- janito/change/analysis/view/__init__.py +0 -9
- janito/change/analysis/view/terminal.py +0 -181
- janito/change/applier/__init__.py +0 -5
- janito/change/applier/file.py +0 -58
- janito/change/applier/main.py +0 -156
- janito/change/applier/text.py +0 -247
- janito/change/applier/workspace_dir.py +0 -58
- janito/change/core.py +0 -124
- janito/change/history.py +0 -44
- janito/change/operations.py +0 -7
- janito/change/parser.py +0 -287
- janito/change/play.py +0 -54
- janito/change/preview.py +0 -82
- janito/change/prompts.py +0 -121
- janito/change/test.py +0 -0
- janito/change/validator.py +0 -269
- janito/change/viewer/__init__.py +0 -11
- janito/change/viewer/content.py +0 -66
- janito/change/viewer/diff.py +0 -43
- janito/change/viewer/panels.py +0 -533
- janito/change/viewer/styling.py +0 -114
- janito/change/viewer/themes.py +0 -55
- janito/clear_statement_parser/clear_statement_format.txt +0 -328
- janito/clear_statement_parser/examples.txt +0 -326
- janito/clear_statement_parser/models.py +0 -104
- janito/clear_statement_parser/parser.py +0 -496
- janito/cli/__init__.py +0 -2
- janito/cli/base.py +0 -30
- janito/cli/commands.py +0 -88
- janito/cli/functions.py +0 -111
- janito/cli/history.py +0 -61
- janito/cli/registry.py +0 -26
- janito/common.py +0 -80
- janito/demo/__init__.py +0 -4
- janito/demo/data.py +0 -13
- janito/demo/mock_data.py +0 -20
- janito/demo/operations.py +0 -45
- janito/demo/runner.py +0 -59
- janito/demo/scenarios.py +0 -32
- janito/prompt.py +0 -36
- janito/qa.py +0 -57
- janito/review.py +0 -13
- janito/search_replace/README.md +0 -192
- janito/search_replace/__init__.py +0 -7
- janito/search_replace/__main__.py +0 -21
- janito/search_replace/core.py +0 -120
- janito/search_replace/logger.py +0 -35
- janito/search_replace/parser.py +0 -52
- janito/search_replace/play.py +0 -61
- janito/search_replace/replacer.py +0 -36
- janito/search_replace/searcher.py +0 -411
- janito/search_replace/strategy_result.py +0 -10
- janito/shell/__init__.py +0 -38
- janito/shell/bus.py +0 -31
- janito/shell/commands.py +0 -136
- janito/shell/history.py +0 -20
- janito/shell/processor.py +0 -32
- janito/shell/prompt.py +0 -48
- janito/shell/registry.py +0 -60
- janito/tui/__init__.py +0 -21
- janito/tui/base.py +0 -22
- janito/tui/flows/__init__.py +0 -5
- janito/tui/flows/changes.py +0 -65
- janito/tui/flows/content.py +0 -128
- janito/tui/flows/selection.py +0 -117
- janito/tui/screens/__init__.py +0 -3
- janito/tui/screens/app.py +0 -1
- janito/version.py +0 -23
- janito/workspace/__init__.py +0 -6
- janito/workspace/analysis.py +0 -121
- janito/workspace/show.py +0 -141
- janito/workspace/stats.py +0 -43
- janito/workspace/types.py +0 -98
- janito/workspace/workset.py +0 -108
- janito/workspace/workspace.py +0 -114
- janito-0.7.0.dist-info/METADATA +0 -167
- janito-0.7.0.dist-info/RECORD +0 -96
- janito-0.7.0.dist-info/entry_points.txt +0 -2
janito/cli/commands.py
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from typing import Optional, List
|
3
|
-
from rich.console import Console
|
4
|
-
from rich.text import Text
|
5
|
-
|
6
|
-
from janito.agents import AIAgent, agent
|
7
|
-
from janito.workspace import workset
|
8
|
-
from janito.config import config
|
9
|
-
from janito.change.core import process_change_request
|
10
|
-
from janito.change.play import play_saved_changes
|
11
|
-
from janito.cli.history import save_to_history
|
12
|
-
from janito.qa import ask_question, display_answer
|
13
|
-
from janito.demo import DemoRunner
|
14
|
-
from janito.demo.data import get_demo_scenarios
|
15
|
-
|
16
|
-
console = Console()
|
17
|
-
|
18
|
-
def handle_ask(question: str):
|
19
|
-
"""Process a question about the codebase"""
|
20
|
-
|
21
|
-
if config.tui:
|
22
|
-
answer = ask_question(question)
|
23
|
-
from janito.tui import TuiApp
|
24
|
-
app = TuiApp(content=answer)
|
25
|
-
app.run()
|
26
|
-
else:
|
27
|
-
answer = ask_question(question)
|
28
|
-
display_answer(answer)
|
29
|
-
|
30
|
-
def handle_scan():
|
31
|
-
"""Preview files that would be analyzed"""
|
32
|
-
workset.show()
|
33
|
-
|
34
|
-
def handle_play(filepath: Path):
|
35
|
-
"""Replay a saved changes or debug file"""
|
36
|
-
play_saved_changes(filepath)
|
37
|
-
|
38
|
-
def is_dir_empty(path: Path) -> bool:
|
39
|
-
"""Check if directory is empty or only contains empty directories."""
|
40
|
-
if not path.is_dir():
|
41
|
-
return False
|
42
|
-
|
43
|
-
for item in path.iterdir():
|
44
|
-
if item.name.startswith(('.', '__pycache__')):
|
45
|
-
continue
|
46
|
-
if item.is_file():
|
47
|
-
return False
|
48
|
-
if item.is_dir() and not is_dir_empty(item):
|
49
|
-
return False
|
50
|
-
return True
|
51
|
-
|
52
|
-
def handle_request(request: str, preview_only: bool = False):
|
53
|
-
"""Process modification request"""
|
54
|
-
is_empty = is_dir_empty(config.workspace_dir)
|
55
|
-
if is_empty and not config.include:
|
56
|
-
console.print("\n[bold blue]Empty directory - will create new files as needed[/bold blue]")
|
57
|
-
|
58
|
-
success, history_file = process_change_request(request, preview_only)
|
59
|
-
|
60
|
-
if success and history_file and config.verbose:
|
61
|
-
try:
|
62
|
-
rel_path = history_file.relative_to(config.workspace_dir)
|
63
|
-
console.print(f"\nChanges saved to: ./{rel_path}")
|
64
|
-
except ValueError:
|
65
|
-
console.print(f"\nChanges saved to: {history_file}")
|
66
|
-
elif not success:
|
67
|
-
console.print("[red]Failed to process change request[/red]")
|
68
|
-
|
69
|
-
# Save request and response to history
|
70
|
-
if agent.last_response:
|
71
|
-
save_to_history(request, agent.last_response)
|
72
|
-
|
73
|
-
def handle_demo():
|
74
|
-
"""Run demo scenarios"""
|
75
|
-
runner = DemoRunner()
|
76
|
-
|
77
|
-
# Add predefined scenarios
|
78
|
-
for scenario in get_demo_scenarios():
|
79
|
-
runner.add_scenario(scenario)
|
80
|
-
|
81
|
-
# Preview and run scenarios
|
82
|
-
console.print("\n[bold cyan]Demo Scenarios Preview:[/bold cyan]")
|
83
|
-
runner.preview_changes()
|
84
|
-
|
85
|
-
console.print("\n[bold cyan]Running Demo Scenarios:[/bold cyan]")
|
86
|
-
runner.run_all()
|
87
|
-
|
88
|
-
console.print("\n[green]Demo completed successfully![/green]")
|
janito/cli/functions.py
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
import tempfile
|
3
|
-
from datetime import datetime, timezone
|
4
|
-
from pathlib import Path
|
5
|
-
from typing import List, Optional
|
6
|
-
|
7
|
-
import typer
|
8
|
-
from rich.console import Console
|
9
|
-
from rich.markdown import Markdown
|
10
|
-
from rich.panel import Panel
|
11
|
-
from rich.prompt import Confirm, Prompt
|
12
|
-
from rich.text import Text
|
13
|
-
|
14
|
-
from janito.agents import AIAgent
|
15
|
-
from janito.common import progress_send_message
|
16
|
-
from janito.config import config
|
17
|
-
from janito.qa import ask_question, display_answer
|
18
|
-
from janito.workspace import collect_files_content
|
19
|
-
|
20
|
-
|
21
|
-
def prompt_user(message: str, choices: List[str] = None) -> str:
|
22
|
-
"""Display a simple user prompt with optional choices"""
|
23
|
-
console = Console()
|
24
|
-
|
25
|
-
if choices:
|
26
|
-
console.print(f"\n[cyan]Options: {', '.join(choices)}[/cyan]")
|
27
|
-
|
28
|
-
return Prompt.ask(f"[bold cyan]> {message}[/bold cyan]")
|
29
|
-
|
30
|
-
def validate_option_letter(letter: str, options: dict) -> bool:
|
31
|
-
"""Validate if the given letter is a valid option or 'M' for modify"""
|
32
|
-
return letter.upper() in options or letter.upper() == 'M'
|
33
|
-
|
34
|
-
def get_option_selection() -> str:
|
35
|
-
"""Get user input for option selection"""
|
36
|
-
console = Console()
|
37
|
-
console.print("\n[cyan]Enter option letter or 'M' to modify request[/cyan]")
|
38
|
-
|
39
|
-
while True:
|
40
|
-
letter = Prompt.ask("[bold cyan]Select option[/bold cyan]").strip().upper()
|
41
|
-
if letter == 'M' or (letter.isalpha() and len(letter) == 1):
|
42
|
-
return letter
|
43
|
-
|
44
|
-
console.print("[red]Please enter a valid letter or 'M'[/red]")
|
45
|
-
|
46
|
-
def get_change_history_path() -> Path:
|
47
|
-
"""Create and return the changes history directory path"""
|
48
|
-
changes_history_dir = config.workspace_dir / '.janito' / 'change_history'
|
49
|
-
changes_history_dir.mkdir(parents=True, exist_ok=True)
|
50
|
-
return changes_history_dir
|
51
|
-
|
52
|
-
def get_timestamp() -> str:
|
53
|
-
"""Get current UTC timestamp in YMD_HMS format with leading zeros"""
|
54
|
-
return datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')
|
55
|
-
|
56
|
-
def save_prompt_to_file(prompt: str) -> Path:
|
57
|
-
"""Save prompt to a named temporary file that won't be deleted"""
|
58
|
-
temp_file = tempfile.NamedTemporaryFile(prefix='selected_', suffix='.txt', delete=False)
|
59
|
-
temp_path = Path(temp_file.name)
|
60
|
-
temp_path.write_text(prompt)
|
61
|
-
return temp_path
|
62
|
-
|
63
|
-
def save_to_file(content: str, prefix: str) -> Path:
|
64
|
-
"""Save content to a timestamped file in changes history directory"""
|
65
|
-
changes_history_dir = get_change_history_path()
|
66
|
-
timestamp = get_timestamp()
|
67
|
-
filename = f"{timestamp}_{prefix}.txt"
|
68
|
-
file_path = changes_history_dir / filename
|
69
|
-
file_path.write_text(content)
|
70
|
-
return file_path
|
71
|
-
|
72
|
-
def modify_request(request: str) -> str:
|
73
|
-
"""Display current request and get modified version with improved formatting"""
|
74
|
-
console = Console()
|
75
|
-
|
76
|
-
# Display current request in a panel with clear formatting
|
77
|
-
console.print("\n[bold cyan]Current Request:[/bold cyan]")
|
78
|
-
console.print(Panel(
|
79
|
-
Text(request, style="white"),
|
80
|
-
border_style="blue",
|
81
|
-
title="Previous Request",
|
82
|
-
padding=(1, 2)
|
83
|
-
))
|
84
|
-
|
85
|
-
# Get modified request with clear prompt
|
86
|
-
console.print("\n[bold cyan]Enter modified request below:[/bold cyan]")
|
87
|
-
console.print("[dim](Press Enter to submit, Ctrl+C to cancel)[/dim]")
|
88
|
-
try:
|
89
|
-
new_request = prompt_user("Modified request")
|
90
|
-
if not new_request.strip():
|
91
|
-
console.print("[yellow]No changes made, keeping original request[/yellow]")
|
92
|
-
return request
|
93
|
-
return new_request
|
94
|
-
except KeyboardInterrupt:
|
95
|
-
console.print("\n[yellow]Modification cancelled, keeping original request[/yellow]")
|
96
|
-
return request
|
97
|
-
|
98
|
-
|
99
|
-
def read_stdin() -> str:
|
100
|
-
"""Read input from stdin until EOF"""
|
101
|
-
console = Console()
|
102
|
-
console.print("[dim]Enter your input (press Ctrl+D when finished):[/dim]")
|
103
|
-
return sys.stdin.read().strip()
|
104
|
-
|
105
|
-
def process_question(question: str) -> None:
|
106
|
-
"""Process a question about the codebase"""
|
107
|
-
paths_to_scan = [config.workspace_dir] if not config.include else config.include
|
108
|
-
files_content = collect_files_content(paths_to_scan)
|
109
|
-
answer = ask_question(question, files_content)
|
110
|
-
display_answer(answer)
|
111
|
-
|
janito/cli/history.py
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from datetime import datetime, timezone
|
3
|
-
from typing import List
|
4
|
-
from rich.console import Console
|
5
|
-
from rich.table import Table
|
6
|
-
from janito.config import config
|
7
|
-
|
8
|
-
def get_history_path() -> Path:
|
9
|
-
"""Get the path to the history directory"""
|
10
|
-
history_dir = config.workspace_dir / '.janito' / 'history'
|
11
|
-
history_dir.mkdir(parents=True, exist_ok=True)
|
12
|
-
return history_dir
|
13
|
-
|
14
|
-
def save_to_history(request: str, response: str) -> None:
|
15
|
-
"""Save a request and its response to the history file"""
|
16
|
-
history_dir = get_history_path()
|
17
|
-
timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%d_%H%M%S')
|
18
|
-
history_file = history_dir / f"{timestamp}_request.txt"
|
19
|
-
|
20
|
-
content = f"""Request: {request}
|
21
|
-
Timestamp: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')}
|
22
|
-
|
23
|
-
Response:
|
24
|
-
{response}
|
25
|
-
"""
|
26
|
-
history_file.write_text(content)
|
27
|
-
|
28
|
-
def display_history() -> None:
|
29
|
-
"""Display the history of requests"""
|
30
|
-
console = Console()
|
31
|
-
history_dir = get_history_path()
|
32
|
-
|
33
|
-
if not history_dir.exists():
|
34
|
-
console.print("[yellow]No history found[/yellow]")
|
35
|
-
return
|
36
|
-
|
37
|
-
table = Table(title="Request History")
|
38
|
-
table.add_column("Timestamp", style="cyan")
|
39
|
-
table.add_column("Request", style="white")
|
40
|
-
table.add_column("File", style="dim")
|
41
|
-
|
42
|
-
history_files = sorted(history_dir.glob("*_request.txt"), reverse=True)
|
43
|
-
|
44
|
-
if not history_files:
|
45
|
-
console.print("[yellow]No history found[/yellow]")
|
46
|
-
return
|
47
|
-
|
48
|
-
for history_file in history_files:
|
49
|
-
try:
|
50
|
-
content = history_file.read_text()
|
51
|
-
request_line = next(line for line in content.splitlines() if line.startswith("Request:"))
|
52
|
-
timestamp_line = next(line for line in content.splitlines() if line.startswith("Timestamp:"))
|
53
|
-
|
54
|
-
request = request_line.replace("Request:", "").strip()
|
55
|
-
timestamp = timestamp_line.replace("Timestamp:", "").strip()
|
56
|
-
|
57
|
-
table.add_row(timestamp, request, history_file.name)
|
58
|
-
except Exception as e:
|
59
|
-
console.print(f"[red]Error reading {history_file}: {e}[/red]")
|
60
|
-
|
61
|
-
console.print(table)
|
janito/cli/registry.py
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
from typing import Callable, Dict
|
2
|
-
from dataclasses import dataclass
|
3
|
-
|
4
|
-
@dataclass
|
5
|
-
class Command:
|
6
|
-
name: str
|
7
|
-
handler: Callable
|
8
|
-
help_text: str
|
9
|
-
|
10
|
-
class CommandRegistry:
|
11
|
-
def __init__(self):
|
12
|
-
self._commands: Dict[str, Command] = {}
|
13
|
-
|
14
|
-
def register(self, name: str, help_text: str):
|
15
|
-
def decorator(handler: Callable):
|
16
|
-
self._commands[name] = Command(name, handler, help_text)
|
17
|
-
return handler
|
18
|
-
return decorator
|
19
|
-
|
20
|
-
def get_command(self, name: str) -> Command:
|
21
|
-
return self._commands.get(name)
|
22
|
-
|
23
|
-
def get_all_commands(self) -> Dict[str, Command]:
|
24
|
-
return self._commands
|
25
|
-
|
26
|
-
registry = CommandRegistry()
|
janito/common.py
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
2
|
-
from rich.console import Console
|
3
|
-
from rich.rule import Rule
|
4
|
-
from janito.agents import agent
|
5
|
-
from .config import config
|
6
|
-
from rich import print
|
7
|
-
from threading import Event
|
8
|
-
|
9
|
-
""" CACHE USAGE SUMMARY
|
10
|
-
https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching
|
11
|
-
cache_creation_input_tokens: Number of tokens written to the cache when creating a new entry.
|
12
|
-
cache_read_input_tokens: Number of tokens retrieved from the cache for this request.
|
13
|
-
input_tokens: Number of input tokens which were not read from or used to create a cache.
|
14
|
-
"""
|
15
|
-
|
16
|
-
from janito.prompt import build_system_prompt
|
17
|
-
|
18
|
-
console = Console()
|
19
|
-
|
20
|
-
def progress_send_message(message: str) -> str:
|
21
|
-
"""Send a message to the AI agent with progress indication.
|
22
|
-
|
23
|
-
Displays a progress spinner while waiting for the agent's response and shows
|
24
|
-
token usage statistics after receiving the response.
|
25
|
-
|
26
|
-
Args:
|
27
|
-
message: The message to send to the AI agent
|
28
|
-
|
29
|
-
Returns:
|
30
|
-
str: The response text from the AI agent
|
31
|
-
|
32
|
-
Note:
|
33
|
-
If the request fails or is canceled, returns the error message as a string
|
34
|
-
"""
|
35
|
-
system_message = build_system_prompt()
|
36
|
-
if config.debug:
|
37
|
-
console.print("[yellow]======= Sending message[/yellow]")
|
38
|
-
print(system_message)
|
39
|
-
print(message)
|
40
|
-
console.print("[yellow]======= End of message[/yellow]")
|
41
|
-
|
42
|
-
with Progress(
|
43
|
-
SpinnerColumn(),
|
44
|
-
TextColumn("[progress.description]{task.description}", justify="center"),
|
45
|
-
TimeElapsedColumn(),
|
46
|
-
) as progress:
|
47
|
-
task = progress.add_task("Waiting for response from AI agent...", total=None)
|
48
|
-
response = agent.send_message(message, system_message=system_message)
|
49
|
-
progress.update(task, completed=True)
|
50
|
-
|
51
|
-
if config.debug:
|
52
|
-
console.print("[yellow]======= Received response[/yellow]")
|
53
|
-
print(response)
|
54
|
-
console.print("[yellow]======= End of response[/yellow]")
|
55
|
-
|
56
|
-
response_text = response.content[0].text if hasattr(response, 'content') else str(response)
|
57
|
-
|
58
|
-
# Add token usage summary with detailed cache info
|
59
|
-
if hasattr(response, 'usage'):
|
60
|
-
usage = response.usage
|
61
|
-
|
62
|
-
direct_input = usage.input_tokens
|
63
|
-
cache_create = usage.cache_creation_input_tokens or 0
|
64
|
-
cache_read = usage.cache_read_input_tokens or 0
|
65
|
-
total_input = direct_input + cache_create + cache_read
|
66
|
-
|
67
|
-
# Calculate percentages relative to total input
|
68
|
-
create_pct = (cache_create / total_input * 100) if cache_create else 0
|
69
|
-
read_pct = (cache_read / total_input * 100) if cache_read else 0
|
70
|
-
direct_pct = (direct_input / total_input * 100) if direct_input else 0
|
71
|
-
output_ratio = (usage.output_tokens / total_input * 100)
|
72
|
-
|
73
|
-
# Compact single-line token usage summary
|
74
|
-
usage_text = f"[cyan]In: [/][bold green]{total_input:,} - direct: {direct_input} ({direct_pct:.1f}%))[/] [cyan]Out:[/] [bold yellow]{usage.output_tokens:,}[/][dim]({output_ratio:.1f}%)[/]"
|
75
|
-
if cache_create or cache_read:
|
76
|
-
cache_text = f" [magenta]Input Cache:[/] [blue]Write:{cache_create:,}[/][dim]({create_pct:.1f}%)[/] [green]Read:{cache_read:,}[/][dim]({read_pct:.1f}%)[/]"
|
77
|
-
usage_text += cache_text
|
78
|
-
console.print(Rule(usage_text, style="cyan"))
|
79
|
-
|
80
|
-
return response_text
|
janito/demo/__init__.py
DELETED
janito/demo/data.py
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
from typing import Dict, List
|
2
|
-
from .scenarios import DemoScenario
|
3
|
-
from .mock_data import get_mock_changes
|
4
|
-
|
5
|
-
def get_demo_scenarios() -> List[DemoScenario]:
|
6
|
-
"""Get list of predefined demo scenarios"""
|
7
|
-
return [
|
8
|
-
DemoScenario(
|
9
|
-
name="File Operations Demo",
|
10
|
-
description="Demonstrate various file operations with change viewer",
|
11
|
-
changes=get_mock_changes()
|
12
|
-
)
|
13
|
-
]
|
janito/demo/mock_data.py
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
from typing import List
|
2
|
-
from .operations import CreateOperation, ModifyOperation, RemoveOperation, MockOperation
|
3
|
-
|
4
|
-
def get_mock_changes() -> List[MockOperation]:
|
5
|
-
"""Get predefined mock changes for demo"""
|
6
|
-
return [
|
7
|
-
CreateOperation(
|
8
|
-
name="example/hello.py",
|
9
|
-
content="def greet():\n print('Hello, World!')\n"
|
10
|
-
),
|
11
|
-
ModifyOperation(
|
12
|
-
name="example/utils.py",
|
13
|
-
content="def process():\n return 'Processed'\n",
|
14
|
-
original_content="def old_process():\n return 'Old'\n"
|
15
|
-
),
|
16
|
-
RemoveOperation(
|
17
|
-
name="example/obsolete.py",
|
18
|
-
original_content="# Obsolete code\n"
|
19
|
-
)
|
20
|
-
]
|
janito/demo/operations.py
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
|
-
from typing import List, Optional
|
3
|
-
from enum import Enum, auto
|
4
|
-
from pathlib import Path
|
5
|
-
|
6
|
-
class MockOperationType(Enum):
|
7
|
-
CREATE = auto()
|
8
|
-
MODIFY = auto()
|
9
|
-
REMOVE = auto()
|
10
|
-
|
11
|
-
@dataclass
|
12
|
-
class MockOperation:
|
13
|
-
"""Base class for mock operations"""
|
14
|
-
operation_type: MockOperationType
|
15
|
-
name: str
|
16
|
-
reason: str
|
17
|
-
|
18
|
-
@dataclass
|
19
|
-
class CreateOperation(MockOperation):
|
20
|
-
"""Operation for creating new files"""
|
21
|
-
content: str
|
22
|
-
|
23
|
-
def __init__(self, name: str, content: str, reason: str = "Create new file"):
|
24
|
-
super().__init__(MockOperationType.CREATE, name, reason)
|
25
|
-
self.content = content
|
26
|
-
|
27
|
-
@dataclass
|
28
|
-
class ModifyOperation(MockOperation):
|
29
|
-
"""Operation for modifying existing files"""
|
30
|
-
content: str
|
31
|
-
original_content: str
|
32
|
-
|
33
|
-
def __init__(self, name: str, content: str, original_content: str, reason: str = "Modify existing file"):
|
34
|
-
super().__init__(MockOperationType.MODIFY, name, reason)
|
35
|
-
self.content = content
|
36
|
-
self.original_content = original_content
|
37
|
-
|
38
|
-
@dataclass
|
39
|
-
class RemoveOperation(MockOperation):
|
40
|
-
"""Operation for removing files"""
|
41
|
-
original_content: Optional[str] = None
|
42
|
-
|
43
|
-
def __init__(self, name: str, original_content: Optional[str] = None, reason: str = "Remove file"):
|
44
|
-
super().__init__(MockOperationType.REMOVE, name, reason)
|
45
|
-
self.original_content = original_content
|
janito/demo/runner.py
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
from typing import List, Optional
|
2
|
-
from pathlib import Path
|
3
|
-
from rich.console import Console
|
4
|
-
from rich.panel import Panel
|
5
|
-
from rich.progress import Progress, SpinnerColumn, TextColumn
|
6
|
-
from .scenarios import DemoScenario
|
7
|
-
from .operations import MockOperationType
|
8
|
-
from ..change.viewer import preview_all_changes
|
9
|
-
from ..change.parser import FileChange, ChangeOperation
|
10
|
-
|
11
|
-
class DemoRunner:
|
12
|
-
def __init__(self):
|
13
|
-
self.console = Console()
|
14
|
-
self.scenarios: List[DemoScenario] = []
|
15
|
-
|
16
|
-
def add_scenario(self, scenario: DemoScenario) -> None:
|
17
|
-
"""Add a demo scenario to the runner"""
|
18
|
-
self.scenarios.append(scenario)
|
19
|
-
|
20
|
-
def run_all(self) -> None:
|
21
|
-
"""Run all registered demo scenarios"""
|
22
|
-
with Progress(
|
23
|
-
SpinnerColumn(),
|
24
|
-
TextColumn("[progress.description]{task.description}"),
|
25
|
-
console=self.console
|
26
|
-
) as progress:
|
27
|
-
for scenario in self.scenarios:
|
28
|
-
task = progress.add_task(f"Running scenario: {scenario.name}")
|
29
|
-
self.preview_changes(scenario)
|
30
|
-
progress.update(task, completed=True)
|
31
|
-
|
32
|
-
def preview_changes(self, scenario: Optional[DemoScenario] = None) -> None:
|
33
|
-
"""Preview changes for a scenario using change viewer"""
|
34
|
-
if scenario is None:
|
35
|
-
if not self.scenarios:
|
36
|
-
self.console.print("[yellow]No scenarios to preview[/yellow]")
|
37
|
-
return
|
38
|
-
scenario = self.scenarios[0]
|
39
|
-
|
40
|
-
# Convert mock changes to FileChange objects
|
41
|
-
changes = []
|
42
|
-
for mock in scenario.changes:
|
43
|
-
# Map mock operation type to ChangeOperation
|
44
|
-
operation_map = {
|
45
|
-
MockOperationType.CREATE: ChangeOperation.CREATE_FILE,
|
46
|
-
MockOperationType.MODIFY: ChangeOperation.MODIFY_FILE,
|
47
|
-
MockOperationType.REMOVE: ChangeOperation.REMOVE_FILE
|
48
|
-
}
|
49
|
-
operation = operation_map[mock.operation_type]
|
50
|
-
change = FileChange(
|
51
|
-
operation=operation,
|
52
|
-
name=Path(mock.name),
|
53
|
-
content=mock.content if hasattr(mock, 'content') else None,
|
54
|
-
original_content=mock.original_content if hasattr(mock, 'original_content') else None
|
55
|
-
)
|
56
|
-
changes.append(change)
|
57
|
-
|
58
|
-
# Show changes using change viewer
|
59
|
-
preview_all_changes(self.console, changes)
|
janito/demo/scenarios.py
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
|
-
from typing import List, Dict, Optional
|
3
|
-
from rich.text import Text
|
4
|
-
from pathlib import Path
|
5
|
-
from .operations import MockOperation
|
6
|
-
from .mock_data import get_mock_changes
|
7
|
-
|
8
|
-
@dataclass
|
9
|
-
class DemoScenario:
|
10
|
-
name: str
|
11
|
-
description: str
|
12
|
-
changes: List[MockOperation]
|
13
|
-
|
14
|
-
def get_preview(self) -> Text:
|
15
|
-
"""Get a preview of the changes"""
|
16
|
-
text = Text()
|
17
|
-
text.append(f"Description: {self.description}\n\n", style="cyan")
|
18
|
-
|
19
|
-
# Group changes by operation
|
20
|
-
by_operation = {}
|
21
|
-
for change in self.changes:
|
22
|
-
if change.operation not in by_operation:
|
23
|
-
by_operation[change.operation] = []
|
24
|
-
by_operation[change.operation].append(change)
|
25
|
-
|
26
|
-
# Show changes grouped by operation
|
27
|
-
for operation_type, changes in by_operation.items():
|
28
|
-
text.append(f"\n{operation_type.name.title()} Operations:\n", style="yellow")
|
29
|
-
for change in changes:
|
30
|
-
text.append(f"• {change.name}\n", style="white")
|
31
|
-
|
32
|
-
return text
|
janito/prompt.py
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
from .workspace import workset
|
2
|
-
|
3
|
-
SYSTEM_PROMPT = """I am Janito, your friendly software development buddy.
|
4
|
-
|
5
|
-
I help you with coding tasks while being clear and concise in my responses.
|
6
|
-
|
7
|
-
I have received the following workset for analysis:
|
8
|
-
|
9
|
-
{workset}
|
10
|
-
|
11
|
-
"""
|
12
|
-
|
13
|
-
def build_system_prompt() -> dict:
|
14
|
-
|
15
|
-
system_prompt = [
|
16
|
-
{
|
17
|
-
"type": "text",
|
18
|
-
"text": "You Janito, an AI assistant tasked with analyzing worksets of code. You have received the following workset for analysis:",
|
19
|
-
}
|
20
|
-
]
|
21
|
-
|
22
|
-
blocks = workset.get_cache_blocks()
|
23
|
-
for block in blocks:
|
24
|
-
if not block:
|
25
|
-
continue
|
26
|
-
block_content = ""
|
27
|
-
for file in block:
|
28
|
-
block_content += f'<file name="{file.name}"\n"'
|
29
|
-
block_content += f'<content>\n"{file.content}"\n</content>\n</file>\n'
|
30
|
-
system_prompt.append( {
|
31
|
-
"type": "text",
|
32
|
-
"text": block_content,
|
33
|
-
"cache_control": {"type": "ephemeral"}
|
34
|
-
}
|
35
|
-
)
|
36
|
-
return system_prompt
|
janito/qa.py
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
from rich.console import Console
|
2
|
-
from rich.markdown import Markdown
|
3
|
-
from rich.panel import Panel
|
4
|
-
from rich.rule import Rule
|
5
|
-
from janito.common import progress_send_message
|
6
|
-
from janito.workspace import workset # Updated import
|
7
|
-
|
8
|
-
|
9
|
-
QA_PROMPT = """Please provide a clear and concise answer to the following question about the workset you received above.
|
10
|
-
|
11
|
-
Question: {question}
|
12
|
-
|
13
|
-
Focus on providing factual information and explanations. Do not suggest code changes.
|
14
|
-
Format your response using markdown with appropriate headers and code blocks.
|
15
|
-
"""
|
16
|
-
|
17
|
-
def ask_question(question: str) -> str:
|
18
|
-
"""Process a question about the codebase and return the answer"""
|
19
|
-
# Ensure content is refreshed and analyzed
|
20
|
-
workset.show()
|
21
|
-
|
22
|
-
prompt = QA_PROMPT.format(
|
23
|
-
question=question,
|
24
|
-
)
|
25
|
-
return progress_send_message(prompt)
|
26
|
-
|
27
|
-
|
28
|
-
def display_answer(answer: str, raw: bool = False) -> None:
|
29
|
-
"""Display the answer as markdown with consistent colors"""
|
30
|
-
console = Console()
|
31
|
-
|
32
|
-
# Define consistent colors
|
33
|
-
COLORS = {
|
34
|
-
'primary': '#729FCF', # Soft blue for primary elements
|
35
|
-
'secondary': '#8AE234', # Bright green for actions/success
|
36
|
-
'accent': '#AD7FA8', # Purple for accents
|
37
|
-
'muted': '#7F9F7F', # Muted green for less important text
|
38
|
-
}
|
39
|
-
|
40
|
-
if raw:
|
41
|
-
console.print(answer)
|
42
|
-
return
|
43
|
-
|
44
|
-
# Display markdown answer in a panel with consistent styling
|
45
|
-
answer_panel = Panel(
|
46
|
-
Markdown(answer),
|
47
|
-
title="[bold]Answer[/bold]",
|
48
|
-
title_align="center",
|
49
|
-
border_style=COLORS['primary'],
|
50
|
-
padding=(1, 2)
|
51
|
-
)
|
52
|
-
|
53
|
-
console.print("\n")
|
54
|
-
console.print(Rule(style=COLORS['accent']))
|
55
|
-
console.print(answer_panel)
|
56
|
-
console.print(Rule(style=COLORS['accent']))
|
57
|
-
console.print("\n")
|
janito/review.py
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
from rich.console import Console
|
2
|
-
from rich.markdown import Markdown
|
3
|
-
from janito.common import progress_send_message
|
4
|
-
from janito.agents import AIAgent
|
5
|
-
|
6
|
-
def review_text(text: str, raw: bool = False) -> None:
|
7
|
-
"""Review the provided text using Claude"""
|
8
|
-
console = Console()
|
9
|
-
response = progress_send_message(f"Please review this text and provide feedback:\n\n{text}")
|
10
|
-
if raw:
|
11
|
-
console.print(response)
|
12
|
-
else:
|
13
|
-
console.print(Markdown(response))
|