Random LLM - #34
Conversation
| from core.llm import create_ai_client | ||
| from core.settings import Config | ||
| from core.verbose import set_verbose | ||
| from src.core.github_client import GitHubClient |
There was a problem hiding this comment.
Before this change:
ImportError while importing test module '(...)\horw-issue-title-ai\tests\test_main.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
(...)\Python313\Lib\importlib\__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests\test_main.py:5: in <module>
from src.main import open_issue_event, run, scan_issue_event
src\main.py:6: in <module>
from core.github_client import GitHubClient
E ModuleNotFoundError: No module named 'core'
There was a problem hiding this comment.
Hmm, looks good to me. How did you run the tests? I just ran:
pytestin the project directory.
There was a problem hiding this comment.
I originally ran pytest --cov=src --cov-report=xml --cov-report=html --html=test-report.html --self-contained-html in the project root dir (on Windows, if that matters). Now I've re-tested it with just pytest, after reverting the addition of src., and the same error occurs.
There was a problem hiding this comment.
So it would be nice if you could say how I can reproduce it.
my logs:
(venv) horw@horw-ProArt-P16-H7606WI-H7606WI:~/PycharmProjects/issue-title-ai$ pytest
==================================================================== test session starts =====================================================================
platform linux -- Python 3.11.12, pytest-8.3.5, pluggy-1.5.0
rootdir: /home/horw/PycharmProjects/issue-title-ai
configfile: pyproject.toml
plugins: anyio-4.9.0, socket-0.7.0, cov-6.1.1
collected 68 items
tests/test_github_client.py ............. [ 19%]
tests/test_issue_service.py ........... [ 35%]
tests/test_llm.py ................. [ 60%]
tests/test_main.py ...... [ 69%]
tests/test_settings.py ..................... [100%]
======================================================================= tests coverage =======================================================================
______________________________________________________ coverage: platform linux, python 3.11.12-final-0 ______________________________________________________
Name Stmts Miss Branch BrPart Cover Missing
-----------------------------------------------------------------------
src/core/github_client.py 48 1 8 1 96% 39
src/core/issue_service.py 46 0 12 0 100%
src/core/llm.py 64 0 12 0 100%
src/core/settings.py 98 0 34 1 99% 37->41
src/core/verbose.py 11 1 2 1 85% 7
src/main.py 53 2 8 2 93% 45, 90
-----------------------------------------------------------------------
TOTAL 320 4 76 5 98%
Coverage HTML written to dir htmlcov
Required test coverage of 80.0% reached. Total coverage: 97.73%
===================================================================== 68 passed in 0.94s =====================================================================
(venv) horw@horw-ProArt-P16-H7606WI-H7606WI:~/PycharmProjects/issue-title-ai$
|
No AI-improved title for this PR? :( |
With PRs, it seems harder to achieve this. Actually, it's okay to just look at the PR description, but as I see it, developers usually don't put much effort into the description. So, the main source of truth becomes the diffs — but that makes things more difficult (for sure, not that much more—just a few more steps):
|
|
Thank you for this PR! I just left a few comments. Your solution looks good! |
| if self.explicit_provider: | ||
| return self.ai_providers[self.explicit_provider] | ||
|
|
||
| ai_provider = random.choice(list(self.ai_providers.keys())) # nosec |
There was a problem hiding this comment.
Since Ruff raises this error, use # noqa: S311 to skip it.
|
Fixes #35 (quick fix, not with |
| return ai_providers | ||
|
|
||
| @property | ||
| def ai_provider(self): | ||
| if self.ai_providers: | ||
| if self.explicit_provider: | ||
| return self.ai_providers[self.explicit_provider] | ||
|
|
||
| ai_provider = random.choice(list(self.ai_providers.keys())) | ||
| return self.ai_providers[ai_provider] | ||
| raise ValueError("No LLM API key was provided. Please provide one of the following: deepseek, gemini, openai.") |
There was a problem hiding this comment.
| return ai_providers | |
| @property | |
| def ai_provider(self): | |
| if self.ai_providers: | |
| if self.explicit_provider: | |
| return self.ai_providers[self.explicit_provider] | |
| ai_provider = random.choice(list(self.ai_providers.keys())) | |
| return self.ai_providers[ai_provider] | |
| raise ValueError("No LLM API key was provided. Please provide one of the following: deepseek, gemini, openai.") | |
| if not self.ai_providers: | |
| raise ValueError( | |
| "No LLM API key was provided. Please provide one of the following: deepseek, gemini, openai." | |
| ) | |
| return ai_providers | |
| @property | |
| def ai_provider(self): | |
| ai_provider = random.choice(list(self.ai_providers.keys())) | |
| return self.ai_providers[ai_provider] |
How about we move the login check for No LLM ... into _get_llm_config? That way, ai_provider looks much simpler. WDYT?
There was a problem hiding this comment.
Then in the validation function, ai_provider = self.ai_provider is not needed.
| "deepseek": self.deepseek_api_key, | ||
| } | ||
| self.explicit_provider = os.environ.get("INPUT_AI-PROVIDER", "").lower() | ||
| self._get_llm_configs() |
There was a problem hiding this comment.
I preferred how it was before, with the return value ai_providers, which was then assigned to self.ai_providers. The current function is named get_llm_configs, but in reality, it is doing a setting operation.
| def ai_provider(self): | ||
| ai_provider_name = self.ai_providers[self.explicit_provider] \ | ||
| if self.explicit_provider \ | ||
| else ai_provider = random.choice(list(self.ai_providers.keys())) # noqa: S311 |
There was a problem hiding this comment.
Syntax error : else ai_provider = random...
Also, I don't think using a one-line if-else for a long expression is a good idea—it can easily be converted to a regular if-else statement.
| @property | ||
| def ai_provider(self): | ||
| ai_provider_name = self.ai_providers[self.explicit_provider] \ | ||
| if self.explicit_provider \ | ||
| else ai_provider = random.choice(list(self.ai_providers.keys())) # noqa: S311 | ||
| return self.ai_providers[ai_provider_name] |
There was a problem hiding this comment.
| @property | |
| def ai_provider(self): | |
| ai_provider_name = self.ai_providers[self.explicit_provider] \ | |
| if self.explicit_provider \ | |
| else ai_provider = random.choice(list(self.ai_providers.keys())) # noqa: S311 | |
| return self.ai_providers[ai_provider_name] | |
| @property | |
| def ai_provider(self): | |
| ai_provider = random.choice(list(self.ai_providers.keys())) | |
| return self.ai_providers[ai_provider] |
WDYT about this solution? Yes, it might call random.choice a few more times, even when there's only one element, but code looks simple
|
@horw, any update? Could you run the workflows, please (or configure them to run automatically)? |
Hi! In the workflow, there are two jobs: one is the pre-commit hook, and the other is running pytest. You can easily run them locally with: and |
|
Thanks @horw, I think now all the checks should pass. On my machine only the |
|
@horw, since the tests pass now, are we OK with merging this? |
|
Hi, I will review this PR. One note: we've changed the API, so users who already use our action will encounter a problem because the After you add this, I will help to fix the pre-commit issue, and then we will be ready to merge it. |
|
@horw, I've added the deprecation message. Please check whether it is OK. |
|
@horw, any update with this? |
Closes #11