|
21 | 21 | import http.client |
22 | 22 | import urllib.request |
23 | 23 | import urllib.parse |
| 24 | +import socket |
24 | 25 |
|
25 | 26 | # Set up logging |
26 | 27 | logging.basicConfig( |
@@ -109,6 +110,24 @@ def component(self) -> str: |
109 | 110 | # Default to the first directory name |
110 | 111 | return parts[0] |
111 | 112 |
|
| 113 | + @property |
| 114 | + def is_formatting_change(self) -> bool: |
| 115 | + """Determine if this change is likely just formatting.""" |
| 116 | + if not self.content_diff: |
| 117 | + return False |
| 118 | + |
| 119 | + # Simple heuristics to detect formatting changes |
| 120 | + formatting_indicators = [ |
| 121 | + # Only whitespace changes |
| 122 | + self.content_diff.strip().startswith('diff') and all(line.startswith(('+', '-', ' ')) and line.strip() in ('', '+', '-') for line in self.content_diff.splitlines()[1:] if line and not line.startswith(('---', '+++', 'diff', 'index', '@@'))), |
| 123 | + # Common formatter markers |
| 124 | + 'import format' in self.content_diff.lower(), |
| 125 | + 'prettier' in self.content_diff.lower(), |
| 126 | + 'fmt' in self.content_diff.lower() and len(self.content_diff) < 500 |
| 127 | + ] |
| 128 | + |
| 129 | + return any(formatting_indicators) |
| 130 | + |
112 | 131 |
|
113 | 132 | @dataclass |
114 | 133 | class CommitGroup: |
@@ -207,19 +226,30 @@ def __init__(self, host: str = "http://localhost:11434", model: Optional[str] = |
207 | 226 |
|
208 | 227 | def _get_host_connection(self) -> Tuple[str, int]: |
209 | 228 | """Parse host string and return connection parameters.""" |
210 | | - if self.host.startswith("http://"): |
211 | | - parsed_url = urllib.parse.urlparse(self.host) |
212 | | - host = parsed_url.netloc |
213 | | - port = parsed_url.port or 11434 |
214 | | - elif self.host.startswith("https://"): |
215 | | - parsed_url = urllib.parse.urlparse(self.host) |
216 | | - host = parsed_url.netloc |
217 | | - port = parsed_url.port or 443 |
218 | | - else: |
219 | | - host = self.host |
220 | | - port = 11434 |
| 229 | + try: |
| 230 | + if self.host.startswith("http://"): |
| 231 | + parsed_url = urllib.parse.urlparse(self.host) |
| 232 | + host = parsed_url.netloc.split(':')[0] # Extract only hostname part |
| 233 | + port = parsed_url.port or 11434 |
| 234 | + elif self.host.startswith("https://"): |
| 235 | + parsed_url = urllib.parse.urlparse(self.host) |
| 236 | + host = parsed_url.netloc.split(':')[0] # Extract only hostname part |
| 237 | + port = parsed_url.port or 443 |
| 238 | + else: |
| 239 | + host = self.host.split(':')[0] # Handle case if port is included |
| 240 | + port = 11434 |
221 | 241 |
|
222 | | - return host, port |
| 242 | + # Test connection before returning |
| 243 | + socket.getaddrinfo(host, port) |
| 244 | + return host, port |
| 245 | + except Exception as e: |
| 246 | + logger.warning(f"Connection error to {self.host}: {str(e)}") |
| 247 | + # Fall back to localhost if specified host fails |
| 248 | + if self.host != "localhost" and self.host != "http://localhost:11434": |
| 249 | + logger.info("Trying localhost as fallback") |
| 250 | + self.host = "http://localhost:11434" |
| 251 | + return "localhost", 11434 |
| 252 | + raise |
223 | 253 |
|
224 | 254 | def _get_available_models(self) -> List[str]: |
225 | 255 | """Get a list of available models from Ollama.""" |
@@ -600,7 +630,7 @@ def _ai_subdivide_changes(self, component: str, changes: List[GitChange]) -> Lis |
600 | 630 | 4. The criteria for which files should be included |
601 | 631 | |
602 | 632 | Format each group as JSON: |
603 | | - {"type": "...", "name": "...", "description": "...", "criteria": "..."} |
| 633 | + {{"type": "...", "name": "...", "description": "...", "criteria": "..."}} |
604 | 634 | |
605 | 635 | Separate each group with --- |
606 | 636 | """ |
|
0 commit comments