feat(devgen/modules): streamline provider guard and enhance ManifestInspector flexibility
Add token‑limit error handling and switch git diff to null‑delimited output for reliable file detection.
This commit is contained in:
3 files changed
+30
-20
No files matched your search
@@ -33,6 +33,8 @@ from devgen.utils import (
|
||||
extract_commit_messages,
|
||||
get_commit_dry_run_path,
|
||||
is_file_recent,
|
||||
is_token_limit_error,
|
||||
format_token_limit_error,
|
||||
load_template,
|
||||
render_template,
|
||||
sanitize_ai_commit_message,
|
||||
@@ -241,9 +243,10 @@ class CommitEngine:
|
||||
if not self._process_group(group, group_files, cache_map):
|
||||
failed.append(group)
|
||||
if len(groups) > 1 and i < len(groups) - 1:
|
||||
import time
|
||||
if self.provider != "ollama":
|
||||
import time
|
||||
|
||||
time.sleep(15) # Conservative 4 RPM guard for free-tier
|
||||
time.sleep(15) # Conservative 4 RPM guard for free-tier
|
||||
return failed
|
||||
|
||||
def _process_group(
|
||||
@@ -265,7 +268,7 @@ class CommitEngine:
|
||||
return self._apply_message(group, cache[group], files)
|
||||
|
||||
try:
|
||||
manifest_context = ManifestInspector.summary()
|
||||
manifest_context = ManifestInspector.summary(cwd=self.git.cwd)
|
||||
if manifest_context:
|
||||
self.logger.info("Including manifest context in prompt")
|
||||
with self.console.status(
|
||||
@@ -279,10 +282,15 @@ class CommitEngine:
|
||||
)
|
||||
message = sanitize_ai_commit_message(raw)
|
||||
except Exception as e:
|
||||
self.logger.error(
|
||||
f"Failed to generate message for group {group!r}: {e}",
|
||||
exc_info=True,
|
||||
)
|
||||
if is_token_limit_error(e):
|
||||
msg = format_token_limit_error(self.provider, e, group=group)
|
||||
self.console.print(f"[bold red]{msg}[/bold red]")
|
||||
self.logger.error(msg)
|
||||
else:
|
||||
self.logger.error(
|
||||
f"Failed to generate message for group {group!r}: {e}",
|
||||
exc_info=True,
|
||||
)
|
||||
self.git.reset(files)
|
||||
return False
|
||||
|
||||
|
||||
@@ -143,13 +143,14 @@ class ManifestInspector:
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def summary() -> str:
|
||||
def summary(cwd: Optional[Path] = None) -> str:
|
||||
cwd = cwd or get_git_root() or Path(".")
|
||||
lines = [
|
||||
s
|
||||
for s in (
|
||||
ManifestInspector._pyproject(),
|
||||
ManifestInspector._package_json(),
|
||||
ManifestInspector._requirements(),
|
||||
ManifestInspector._pyproject(cwd),
|
||||
ManifestInspector._package_json(cwd),
|
||||
ManifestInspector._requirements(cwd),
|
||||
)
|
||||
if s
|
||||
]
|
||||
@@ -164,8 +165,8 @@ class ManifestInspector:
|
||||
return re.split(r"[><=!~\[]", spec, 1)[0].strip()
|
||||
|
||||
@staticmethod
|
||||
def _pyproject() -> Optional[str]:
|
||||
path = Path("pyproject.toml")
|
||||
def _pyproject(cwd: Path) -> Optional[str]:
|
||||
path = cwd / "pyproject.toml"
|
||||
if not path.exists():
|
||||
return None
|
||||
try:
|
||||
@@ -186,8 +187,8 @@ class ManifestInspector:
|
||||
return f"[pyproject.toml] {' '.join(parts)}" if parts else None
|
||||
|
||||
@staticmethod
|
||||
def _package_json() -> Optional[str]:
|
||||
path = Path("package.json")
|
||||
def _package_json(cwd: Path) -> Optional[str]:
|
||||
path = cwd / "package.json"
|
||||
if not path.exists():
|
||||
return None
|
||||
try:
|
||||
@@ -203,8 +204,8 @@ class ManifestInspector:
|
||||
return f"[package.json] {' '.join(parts)}" if parts else None
|
||||
|
||||
@staticmethod
|
||||
def _requirements() -> Optional[str]:
|
||||
path = Path("requirements.txt")
|
||||
def _requirements(cwd: Path) -> Optional[str]:
|
||||
path = cwd / "requirements.txt"
|
||||
if not path.exists():
|
||||
return None
|
||||
try:
|
||||
|
||||
@@ -91,15 +91,16 @@ class GitOperator:
|
||||
[
|
||||
"git",
|
||||
"ls-files",
|
||||
"-z",
|
||||
"--deleted",
|
||||
"--modified",
|
||||
"--others",
|
||||
"--exclude-standard",
|
||||
]
|
||||
)
|
||||
files = {f.strip() for f in out.split("\n") if f.strip()}
|
||||
staged_out = self._run(["git", "diff", "--name-only", "--cached"])
|
||||
files.update(f.strip() for f in staged_out.split("\n") if f.strip())
|
||||
files = {f for f in out.split("\0") if f}
|
||||
staged_out = self._run(["git", "diff", "-z", "--name-only", "--cached"])
|
||||
files.update(f for f in staged_out.split("\0") if f)
|
||||
return sorted(files)
|
||||
|
||||
# ------------------------------------------------------------------ actions
|
||||
|
||||
Reference in new issue
Block a user