diff --git a/pyproject.toml b/pyproject.toml index 69abfbf..45544eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,9 @@ Issues = "https://github.com/microsoft/SkillOpt/issues" # skillopt_webui = the Gradio dashboard (installed via the `webui` extra) include = ["skillopt", "skillopt.*", "skillopt_sleep", "skillopt_sleep.*", "skillopt_webui", "skillopt_webui.*", "scripts*"] +[tool.setuptools.package-data] +"*" = ["*.md"] + [tool.ruff] line-length = 120 target-version = "py310" diff --git a/skillopt/model/claude_backend.py b/skillopt/model/claude_backend.py index b2d0e94..75020b1 100644 --- a/skillopt/model/claude_backend.py +++ b/skillopt/model/claude_backend.py @@ -243,7 +243,11 @@ def _assistant_message_schema_wrapper() -> str: def _run_claude_print(*, system: str, prompt: str, model: str, tools: list[dict[str, Any]] | None, tool_choice: str | dict[str, Any] | None, return_message: bool, timeout: int | None, attachments: list[dict[str, Any]] | None = None) -> tuple[str, dict[str, Any], dict[str, int]]: effort = _normalize_reasoning_effort(REASONING_EFFORT) - with tempfile.TemporaryDirectory(prefix="skillopt_claude_") as temp_dir: + # Use mkdtemp + manual rmtree to avoid WinError 32 on Windows + # where the spawned claude/node subprocess still holds a handle + # to the temp directory when the context manager tries to clean up. + temp_dir = tempfile.mkdtemp(prefix="skillopt_claude_") + try: copied_attachments = _copy_attachments_to_temp(attachments or [], temp_dir) prompt_for_cli = _append_attachment_instructions(prompt, copied_attachments) cmd = [CLAUDE_BIN, "-p", "--output-format", "json", "--permission-mode", CLAUDE_PERMISSION_MODE, "--add-dir", temp_dir] @@ -287,6 +291,8 @@ def _run_claude_print(*, system: str, prompt: str, model: str, tools: list[dict[ raw_text, result_event = _extract_result(stream) usage_info = _usage_from_result(result_event) return raw_text, result_event or {}, usage_info + finally: + shutil.rmtree(temp_dir, ignore_errors=True) def _compat_message_from_payload(payload: Any) -> CompatAssistantMessage: