Makefile依存を廃止しPython CLI化・LLMs Provider構造化#2
Conversation
Why: Makefileベースの運用が複雑で拡張性・保守性に課題があったため、Python CLI化し、Providerを柔軟に追加できる構造にする。 What/How: - myder.py(Python CLI)新規作成 - provider/ ディレクトリとサンプルProvider実装 - README.mdに新CLIの使い方とMakefile廃止予定を追記
Why: Makefile依存を廃止し、今後はPython CLI(myder.py)運用へ移行するため。 What/How: - Makefileをリポジトリから削除
Why: Makefileは既に削除されており、「廃止予定」ではなく「廃止済み」とするのが正確なため。 What/How: - README冒頭の案内文を現状に合わせて修正
Why: テスト容易性・保守性向上のため、CLIとProvider管理/実行ロジックを分離し、ユニットテストを追加。 What/How: - myder_core.py新設(Provider管理・実行ロジック集約) - myder.pyはCLI引数処理のみ担当にリファクタ - pytest形式のユニットテスト(tests/test_myder_core.py)追加
Pythonのバイトコードキャッシュ(__pycache__)をバージョン管理対象外とするため、.gitignoreの末尾に追加 開発・CI環境で不要なファイルが混入しないようにするため
.gitignoreに追加済みのため、今後はバージョン管理対象外とする
bin/myder, src/myder_core.py等の新構成に合わせて旧ファイルを削除 テスト・READMEも現状に即して修正
ファイル修正時に生成されたバックアップ(.orig)ファイルを不要のため削除
Provider基底クラス(base.py)新設、OpenRouterProvider実装例追加 myder_core.pyをAPI Key必須設計にリファクタ OpenRouterProviderのユニットテスト追加
CLIエントリポイントとして直接実行できるように修正
DEFAULT_PROVIDER=openrouter, DEFAULT_MODEL=gemini-2.5をmyder_core.pyに定義し、bin/myderで省略時に利用
runサブコマンドでprovider名に応じたAPI KEYをCLI引数・環境変数・.envから取得しrun_providerに渡すよう修正
to_pascal_case関数を追加し、openrouter→OpenRouterProvider等の命名に対応
OpenRouterなどキャメルケース指定で動作する設計に変更
DEFAULT_PROVIDERをopenrouter→OpenRouterに変更し、キャメルケース指定に統一
DEFAULT_MODELを現行推奨モデルに変更
--provider OpenRouter でも provider/openrouter.py をimportし、OpenRouterProviderクラスを参照できるように
Providerのrun()が返す推論結果等が標準出力に表示されるように
mainブランチMakefileのrunターゲット相当のdocker runコマンドをPythonで再現
--model未指定時も常にopenrouter/google/gemini-2.5-pro-exp-03-25:freeを利用するよう統一
現状のCLI設計では参照されていないため不要
ユーザーが利用可能な環境変数オプションをhelp/descriptionに明記
NOMOUNT, FORCE_YESは環境変数だけでなくCLIオプションでも指定可能にし、オプションが優先されるように修正
| def test_run_provider(capsys): | ||
| myder_core.run_provider("sample_provider", model="test-model") | ||
| captured = capsys.readouterr() | ||
| assert "SampleProvider: running with model=test-model" in captured.outdef test_openrouter_provider_properties(): |
There was a problem hiding this comment.
There appears to be a syntax error where a newline is missing between the assert statement and the subsequent function definition. Please insert a newline to separate these statements.
| assert "SampleProvider: running with model=test-model" in captured.outdef test_openrouter_provider_properties(): | |
| assert "SampleProvider: running with model=test-model" in captured.out | |
| def test_openrouter_provider_properties(): |
| def load_provider(name, api_key): | ||
| module = importlib.import_module(f"provider.{name.lower()}") | ||
| class_name = name + "Provider" | ||
| provider_class = getattr(module, class_name) |
There was a problem hiding this comment.
The constructed class name does not match the actual provider class names (e.g., for 'sample_provider', the class is defined as 'Provider', not 'sample_providerProvider'). Consider revising the naming strategy or using a mapping to correctly retrieve the provider class.
| def load_provider(name, api_key): | |
| module = importlib.import_module(f"provider.{name.lower()}") | |
| class_name = name + "Provider" | |
| provider_class = getattr(module, class_name) | |
| import inspect | |
| def load_provider(name, api_key): | |
| module = importlib.import_module(f"provider.{name.lower()}") | |
| provider_class = None | |
| for _, cls in inspect.getmembers(module, inspect.isclass): | |
| if cls.__module__ == module.__name__: | |
| provider_class = cls | |
| break | |
| if provider_class is None: | |
| raise ImportError(f"No valid provider class found in module 'provider.{name.lower()}'") |
Why: PRレビューで指摘された構文エラーとProviderクラス名取得の不整合を解消するため What: テストのassert文とdefの間に改行を追加、inspectによるProviderクラス自動検出に修正 How: Copilotのサジェスト通りに修正
| assert "sample_provider" in providers | ||
|
|
||
| def test_load_provider(): | ||
| provider = myder_core.load_provider("sample_provider") |
There was a problem hiding this comment.
The load_provider function requires an api_key argument, but none is provided here. Consider passing a dummy value (e.g., 'dummy-key') for consistency with the provider initialization.
| provider = myder_core.load_provider("sample_provider") | |
| provider = myder_core.load_provider("sample_provider", api_key="dummy-key") |
| myder_core.run_provider("sample_provider", model="test-model") | ||
| captured = capsys.readouterr() |
There was a problem hiding this comment.
The run_provider function requires an api_key argument as its second parameter. Update the call to include a dummy api_key, such as 'dummy-key'.
| myder_core.run_provider("sample_provider", model="test-model") | |
| captured = capsys.readouterr() | |
| myder_core.run_provider("sample_provider", api_key="dummy-key", model="test-model") |
| import os | ||
|
|
There was a problem hiding this comment.
[nitpick] There is a duplicate import of 'os'. Removing the redundant import at line 6 will clean up the code.
| import os |
Why: PRレビューでapi_key引数漏れとos重複importを指摘されたため What: test_load_provider/test_run_providerにapi_key="dummy-key"追加、src/myder_core.pyの重複import削除 How: Copilotのサジェスト通り修正
| @@ -0,0 +1,3 @@ | |||
| class Provider: | |||
| def run(self, model=None): | |||
| print(f"SampleProvider: running with model={model}") No newline at end of file | |||
There was a problem hiding this comment.
The 'run' method in the sample provider prints its output instead of returning it, which is inconsistent with OpenRouterProvider's implementation. Consider standardizing the behavior across providers by either always returning a string or handling output uniformly.
| print(f"SampleProvider: running with model={model}") | |
| return f"SampleProvider: running with model={model}" |
Why: PRレビューで出力方法の不統一を指摘されたため What: printからreturnに修正し、OpenRouterProviderと統一 How: Copilotのサジェスト通り修正
There was a problem hiding this comment.
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Files not reviewed (1)
- Makefile: Language not supported
Comments suppressed due to low confidence (1)
src/provider/sample_provider.py:1
- [nitpick] Consider renaming the class 'Provider' to 'SampleProvider' to avoid ambiguity with other provider classes and improve clarity.
class Provider:
There was a problem hiding this comment.
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Files not reviewed (1)
- Makefile: Language not supported
Comments suppressed due to low confidence (1)
src/provider/sample_provider.py:1
- [nitpick] Consider renaming the class 'Provider' to 'SampleProvider' for clarity and consistency with other provider classes like 'OpenRouterProvider'.
class Provider:
Why: Providerという名前が曖昧で、親クラスであることを明確にするため What: class Provider → class BaseProvider に変更 How: nitpick指摘に従い修正
概要
--nomountおよび--force-yesオプションを追加openrouter/google/gemini-2.5-pro-exp-03-25:freeに統一主な修正内容
使い方例
確認してほしい点
重要点
runサブコマンドのCLIオプション
デフォルト値・運用
備考