Create the alignment cache directory before the first model call
The client writes each answer as it arrives, so a cache directory that was never created turns every model call into an error - and the fallback would quietly turn the whole book into a mechanical split while the run still reported success. The directory is now created by the command line entry point, and the client is constructed with it rather than having it assigned afterwards. A test pins it. 45 tests, ruff clean.
This commit is contained in:
@@ -692,8 +692,13 @@ def main(argv: list[str] | None = None) -> int:
|
||||
|
||||
llm = None
|
||||
if not args.no_llm:
|
||||
llm = LLM(base_url=args.base_url) if args.base_url else LLM()
|
||||
llm.cache_dir = args.run_dir / "cache"
|
||||
# The cache directory has to exist before the first call: the client
|
||||
# writes the answer as it arrives, and a missing directory would turn
|
||||
# every model answer into an error - which the fallback would then
|
||||
# quietly turn into a mechanical split for the whole book.
|
||||
cache_dir = args.run_dir / "cache"
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
llm = LLM(base_url=args.base_url, cache_dir=cache_dir) if args.base_url else LLM(cache_dir=cache_dir)
|
||||
|
||||
selected = select_chapters(book, args.chapters)
|
||||
chapters: list[tuple[dict, list[ParagraphAlignment]]] = []
|
||||
|
||||
@@ -331,5 +331,71 @@ class DeliveryTests(unittest.TestCase):
|
||||
self.assertNotIn("text", collapsed[0])
|
||||
|
||||
|
||||
class CommandTests(unittest.TestCase):
|
||||
def test_the_cache_directory_is_created_before_the_first_call(self) -> None:
|
||||
"""A missing cache directory would fail every model answer.
|
||||
|
||||
The client writes each answer as it arrives, so a cache directory that
|
||||
was never created turns every model call into an error - and the
|
||||
fallback would quietly turn the whole book into a mechanical split.
|
||||
"""
|
||||
import json
|
||||
import tempfile
|
||||
from unittest import mock
|
||||
|
||||
from align import main
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
book = root / "book.json"
|
||||
book.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"target_language": "zh-CN",
|
||||
"chapters": [
|
||||
{
|
||||
"id": "ch-1",
|
||||
"index": 1,
|
||||
"title": "One",
|
||||
"title_zh": "一",
|
||||
"matter": "body",
|
||||
"paragraphs": [],
|
||||
}
|
||||
],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
bundle = root / "bundle.jsonl"
|
||||
bundle.write_text("", encoding="utf-8")
|
||||
run_dir = root / "runs"
|
||||
run_dir.mkdir()
|
||||
|
||||
seen: dict[str, object] = {}
|
||||
|
||||
class StubLLM:
|
||||
def __init__(self, **kwargs: object) -> None:
|
||||
seen.update(kwargs)
|
||||
|
||||
with mock.patch.object(sys.modules["align"], "LLM", StubLLM):
|
||||
exit_code = main(
|
||||
[
|
||||
"--book",
|
||||
str(book),
|
||||
"--run-dir",
|
||||
str(run_dir),
|
||||
"--out",
|
||||
str(root / "delivery.json"),
|
||||
"--bundle",
|
||||
str(bundle),
|
||||
]
|
||||
)
|
||||
self.assertEqual(exit_code, 0)
|
||||
cache_dir = seen.get("cache_dir")
|
||||
self.assertIsNotNone(cache_dir)
|
||||
assert cache_dir is not None
|
||||
self.assertTrue(Path(cache_dir).is_dir())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user