thonny-codemate 0.1.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.
- thonny_codemate-0.1.0.dist-info/METADATA +307 -0
- thonny_codemate-0.1.0.dist-info/RECORD +27 -0
- thonny_codemate-0.1.0.dist-info/WHEEL +5 -0
- thonny_codemate-0.1.0.dist-info/licenses/LICENSE +21 -0
- thonny_codemate-0.1.0.dist-info/top_level.txt +1 -0
- thonnycontrib/__init__.py +1 -0
- thonnycontrib/thonny_codemate/__init__.py +397 -0
- thonnycontrib/thonny_codemate/api.py +154 -0
- thonnycontrib/thonny_codemate/context_manager.py +296 -0
- thonnycontrib/thonny_codemate/external_providers.py +714 -0
- thonnycontrib/thonny_codemate/i18n.py +506 -0
- thonnycontrib/thonny_codemate/llm_client.py +841 -0
- thonnycontrib/thonny_codemate/message_virtualization.py +136 -0
- thonnycontrib/thonny_codemate/model_manager.py +515 -0
- thonnycontrib/thonny_codemate/performance_monitor.py +141 -0
- thonnycontrib/thonny_codemate/prompts.py +102 -0
- thonnycontrib/thonny_codemate/ui/__init__.py +1 -0
- thonnycontrib/thonny_codemate/ui/chat_view.py +687 -0
- thonnycontrib/thonny_codemate/ui/chat_view_html.py +1299 -0
- thonnycontrib/thonny_codemate/ui/custom_prompt_dialog.py +175 -0
- thonnycontrib/thonny_codemate/ui/markdown_renderer.py +484 -0
- thonnycontrib/thonny_codemate/ui/model_download_dialog.py +355 -0
- thonnycontrib/thonny_codemate/ui/settings_dialog.py +1218 -0
- thonnycontrib/thonny_codemate/utils/__init__.py +25 -0
- thonnycontrib/thonny_codemate/utils/constants.py +138 -0
- thonnycontrib/thonny_codemate/utils/error_messages.py +92 -0
- thonnycontrib/thonny_codemate/utils/unified_error_handler.py +310 -0
@@ -0,0 +1,141 @@
|
|
1
|
+
"""
|
2
|
+
パフォーマンスモニタリングユーティリティ
|
3
|
+
実行時間の計測とボトルネックの特定
|
4
|
+
"""
|
5
|
+
import time
|
6
|
+
import functools
|
7
|
+
import logging
|
8
|
+
from typing import Callable, Dict, Any
|
9
|
+
from collections import defaultdict
|
10
|
+
import threading
|
11
|
+
|
12
|
+
logger = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
|
15
|
+
class PerformanceMonitor:
|
16
|
+
"""パフォーマンス統計を収集するクラス"""
|
17
|
+
|
18
|
+
def __init__(self):
|
19
|
+
self.stats = defaultdict(lambda: {
|
20
|
+
'count': 0,
|
21
|
+
'total_time': 0.0,
|
22
|
+
'min_time': float('inf'),
|
23
|
+
'max_time': 0.0
|
24
|
+
})
|
25
|
+
self._lock = threading.Lock()
|
26
|
+
|
27
|
+
def record(self, operation: str, duration: float):
|
28
|
+
"""操作の実行時間を記録"""
|
29
|
+
with self._lock:
|
30
|
+
stat = self.stats[operation]
|
31
|
+
stat['count'] += 1
|
32
|
+
stat['total_time'] += duration
|
33
|
+
stat['min_time'] = min(stat['min_time'], duration)
|
34
|
+
stat['max_time'] = max(stat['max_time'], duration)
|
35
|
+
|
36
|
+
def get_stats(self) -> Dict[str, Dict[str, Any]]:
|
37
|
+
"""統計情報を取得"""
|
38
|
+
with self._lock:
|
39
|
+
result = {}
|
40
|
+
for operation, stat in self.stats.items():
|
41
|
+
if stat['count'] > 0:
|
42
|
+
result[operation] = {
|
43
|
+
'count': stat['count'],
|
44
|
+
'total_time': stat['total_time'],
|
45
|
+
'average_time': stat['total_time'] / stat['count'],
|
46
|
+
'min_time': stat['min_time'],
|
47
|
+
'max_time': stat['max_time']
|
48
|
+
}
|
49
|
+
return result
|
50
|
+
|
51
|
+
def log_stats(self):
|
52
|
+
"""統計情報をログに出力"""
|
53
|
+
stats = self.get_stats()
|
54
|
+
if not stats:
|
55
|
+
return
|
56
|
+
|
57
|
+
logger.info("=== Performance Statistics ===")
|
58
|
+
for operation, stat in sorted(stats.items(), key=lambda x: x[1]['total_time'], reverse=True):
|
59
|
+
logger.info(
|
60
|
+
f"{operation}: "
|
61
|
+
f"count={stat['count']}, "
|
62
|
+
f"avg={stat['average_time']*1000:.2f}ms, "
|
63
|
+
f"min={stat['min_time']*1000:.2f}ms, "
|
64
|
+
f"max={stat['max_time']*1000:.2f}ms, "
|
65
|
+
f"total={stat['total_time']:.2f}s"
|
66
|
+
)
|
67
|
+
|
68
|
+
|
69
|
+
# グローバルインスタンス
|
70
|
+
_monitor = PerformanceMonitor()
|
71
|
+
|
72
|
+
|
73
|
+
def measure_performance(operation: str = None):
|
74
|
+
"""
|
75
|
+
パフォーマンスを計測するデコレーター
|
76
|
+
|
77
|
+
Args:
|
78
|
+
operation: 操作名(None の場合は関数名を使用)
|
79
|
+
"""
|
80
|
+
def decorator(func: Callable) -> Callable:
|
81
|
+
op_name = operation or f"{func.__module__}.{func.__name__}"
|
82
|
+
|
83
|
+
@functools.wraps(func)
|
84
|
+
def wrapper(*args, **kwargs):
|
85
|
+
start_time = time.time()
|
86
|
+
try:
|
87
|
+
result = func(*args, **kwargs)
|
88
|
+
return result
|
89
|
+
finally:
|
90
|
+
duration = time.time() - start_time
|
91
|
+
_monitor.record(op_name, duration)
|
92
|
+
|
93
|
+
# 遅い操作を警告
|
94
|
+
if duration > 1.0:
|
95
|
+
logger.warning(f"Slow operation: {op_name} took {duration:.2f}s")
|
96
|
+
|
97
|
+
return wrapper
|
98
|
+
return decorator
|
99
|
+
|
100
|
+
|
101
|
+
class Timer:
|
102
|
+
"""コンテキストマネージャーとして使用できるタイマー"""
|
103
|
+
|
104
|
+
def __init__(self, operation: str):
|
105
|
+
self.operation = operation
|
106
|
+
self.start_time = None
|
107
|
+
|
108
|
+
def __enter__(self):
|
109
|
+
self.start_time = time.time()
|
110
|
+
return self
|
111
|
+
|
112
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
113
|
+
if self.start_time:
|
114
|
+
duration = time.time() - self.start_time
|
115
|
+
_monitor.record(self.operation, duration)
|
116
|
+
|
117
|
+
|
118
|
+
def get_performance_stats() -> Dict[str, Dict[str, Any]]:
|
119
|
+
"""現在のパフォーマンス統計を取得"""
|
120
|
+
return _monitor.get_stats()
|
121
|
+
|
122
|
+
|
123
|
+
def log_performance_stats():
|
124
|
+
"""パフォーマンス統計をログに出力"""
|
125
|
+
_monitor.log_stats()
|
126
|
+
|
127
|
+
|
128
|
+
def reset_performance_stats():
|
129
|
+
"""パフォーマンス統計をリセット"""
|
130
|
+
global _monitor
|
131
|
+
_monitor = PerformanceMonitor()
|
132
|
+
|
133
|
+
|
134
|
+
# 使用例:
|
135
|
+
# @measure_performance()
|
136
|
+
# def slow_function():
|
137
|
+
# time.sleep(1)
|
138
|
+
#
|
139
|
+
# with Timer("database_query"):
|
140
|
+
# # データベースクエリ実行
|
141
|
+
# pass
|
@@ -0,0 +1,102 @@
|
|
1
|
+
"""
|
2
|
+
システムプロンプトのテンプレート定数
|
3
|
+
"""
|
4
|
+
|
5
|
+
# デフォルトシステムプロンプトテンプレート(カスタムプロンプトダイアログから取得)
|
6
|
+
DEFAULT_SYSTEM_PROMPT_TEMPLATE = """You are an AI programming assistant integrated into Thonny IDE, helping users write and understand Python code.
|
7
|
+
|
8
|
+
User Information:
|
9
|
+
- Skill Level: {skill_level}
|
10
|
+
- Preferred Language: {language}
|
11
|
+
|
12
|
+
Guidelines:
|
13
|
+
1. Adapt your explanations to the user's skill level:
|
14
|
+
- For beginners: Use simple language, provide detailed explanations, give encouragement
|
15
|
+
- For intermediate: Balance clarity with technical accuracy, introduce best practices
|
16
|
+
- For advanced: Be concise and technical, focus on optimization and design patterns
|
17
|
+
|
18
|
+
2. Provide clear, concise answers focused on learning
|
19
|
+
3. Include code examples when helpful
|
20
|
+
4. Point out best practices and common pitfalls
|
21
|
+
5. Be encouraging and supportive
|
22
|
+
|
23
|
+
When explaining code:
|
24
|
+
- Break down complex concepts based on skill level
|
25
|
+
- Use analogies and real-world examples for beginners
|
26
|
+
- Discuss trade-offs and alternatives for advanced users
|
27
|
+
|
28
|
+
When generating code:
|
29
|
+
- Write clean, readable Python code
|
30
|
+
- Adjust comment density based on skill level
|
31
|
+
- Follow PEP 8 style guidelines
|
32
|
+
- Include appropriate error handling"""
|
33
|
+
|
34
|
+
# 教育向けプリセット
|
35
|
+
EDUCATIONAL_PRESET_TEMPLATE = """You are a friendly and patient Python tutor in Thonny IDE, focused on teaching programming concepts.
|
36
|
+
|
37
|
+
User Profile:
|
38
|
+
- Skill Level: {skill_level}
|
39
|
+
- Language: {language}
|
40
|
+
|
41
|
+
Teaching Approach:
|
42
|
+
1. Explain concepts step-by-step with simple language
|
43
|
+
2. Use real-world analogies to clarify abstract concepts
|
44
|
+
3. Provide plenty of examples with detailed explanations
|
45
|
+
4. Encourage experimentation and learning from mistakes
|
46
|
+
5. Celebrate progress and build confidence
|
47
|
+
|
48
|
+
Code Style:
|
49
|
+
- Write beginner-friendly code with descriptive variable names
|
50
|
+
- Add comprehensive comments explaining each step
|
51
|
+
- Avoid advanced features unless specifically asked
|
52
|
+
- Show multiple ways to solve problems when educational
|
53
|
+
|
54
|
+
Always:
|
55
|
+
- Be patient and encouraging
|
56
|
+
- Answer "why" not just "how"
|
57
|
+
- Suggest next learning steps
|
58
|
+
- Provide exercises to practice new concepts"""
|
59
|
+
|
60
|
+
# プロフェッショナル向けプリセット
|
61
|
+
PROFESSIONAL_PRESET_TEMPLATE = """You are an expert Python developer assistant in Thonny IDE, focused on professional code quality and efficiency.
|
62
|
+
|
63
|
+
Context:
|
64
|
+
- User Level: {skill_level}
|
65
|
+
- Output Language: {language}
|
66
|
+
|
67
|
+
Priorities:
|
68
|
+
1. Write production-ready, efficient code
|
69
|
+
2. Follow industry best practices and design patterns
|
70
|
+
3. Consider performance, scalability, and maintainability
|
71
|
+
4. Include proper error handling and edge cases
|
72
|
+
5. Use type hints and comprehensive docstrings
|
73
|
+
|
74
|
+
Code Standards:
|
75
|
+
- Follow PEP 8 and PEP 257 strictly
|
76
|
+
- Write DRY (Don't Repeat Yourself) code
|
77
|
+
- Implement SOLID principles where applicable
|
78
|
+
- Include unit test examples when relevant
|
79
|
+
|
80
|
+
Communication:
|
81
|
+
- Be concise and technical
|
82
|
+
- Focus on implementation details
|
83
|
+
- Discuss trade-offs and alternatives
|
84
|
+
- Reference relevant documentation and libraries"""
|
85
|
+
|
86
|
+
# 最小限プリセット
|
87
|
+
MINIMAL_PRESET_TEMPLATE = """You are a concise Python coding assistant in Thonny IDE.
|
88
|
+
|
89
|
+
User: {skill_level} level, {language} language
|
90
|
+
|
91
|
+
Rules:
|
92
|
+
- Provide direct, minimal responses
|
93
|
+
- Code first, explanations only if asked
|
94
|
+
- No unnecessary commentary
|
95
|
+
- Focus on solving the immediate problem"""
|
96
|
+
|
97
|
+
# スキルレベルの詳細説明
|
98
|
+
SKILL_LEVEL_DESCRIPTIONS = {
|
99
|
+
"beginner": "beginner (new to programming, needs detailed step-by-step explanations with simple language and lots of encouragement)",
|
100
|
+
"intermediate": "intermediate (has some programming experience, can understand technical concepts but benefits from practical examples and best practices)",
|
101
|
+
"advanced": "advanced (experienced developer, prefers concise technical explanations, interested in architecture and optimization)"
|
102
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
# UI components for Thonny Local LLM Plugin
|