|
31 | 31 | from __future__ import annotations |
32 | 32 |
|
33 | 33 | import dataclasses |
| 34 | +from importlib import metadata |
34 | 35 | from typing import TYPE_CHECKING, Any |
35 | 36 |
|
36 | 37 | from airflow.providers.common.ai.skills import SkillSource, _materialize_skills |
37 | 38 | from airflow.providers.common.ai.utils.toolset_base import validate_max_retries |
38 | 39 |
|
| 40 | +# pydantic-ai-skills 2.0 removed SkillsToolset, leaving only SkillsCapability, so the |
| 41 | +# ``skills`` extra caps it below 2. |
| 42 | +_SUPPORTED_PYDANTIC_AI_SKILLS = ">=1.2.0,<2" |
| 43 | + |
39 | 44 | try: |
40 | 45 | from pydantic_ai.toolsets.abstract import AbstractToolset |
41 | 46 | except ImportError: # pragma: no cover - pydantic-ai is a provider dependency |
@@ -114,13 +119,22 @@ async def for_run(self, ctx: RunContext) -> AbstractToolset: |
114 | 119 |
|
115 | 120 | async def __aenter__(self) -> AgentSkillsToolset: |
116 | 121 | # Resolve + clone at run time, on the worker -- not at DAG-parse time. |
| 122 | + # pydantic-ai-skills is an optional extra, so it is imported here rather than at module level. |
117 | 123 | try: |
118 | | - from pydantic_ai_skills import SkillsToolset |
| 124 | + import pydantic_ai_skills |
119 | 125 | except ImportError as e: |
120 | 126 | raise ValueError( |
121 | 127 | "AgentSkillsToolset requires the optional 'skills' extra: " |
122 | 128 | "pip install 'apache-airflow-providers-common-ai[skills]'." |
123 | 129 | ) from e |
| 130 | + if not hasattr(pydantic_ai_skills, "SkillsToolset"): |
| 131 | + raise ValueError( |
| 132 | + f"AgentSkillsToolset needs pydantic-ai-skills{_SUPPORTED_PYDANTIC_AI_SKILLS}, but " |
| 133 | + f"pydantic-ai-skills {metadata.version('pydantic-ai-skills')} is installed and has no " |
| 134 | + "SkillsToolset. Install a supported version: " |
| 135 | + f"pip install 'pydantic-ai-skills{_SUPPORTED_PYDANTIC_AI_SKILLS}'." |
| 136 | + ) |
| 137 | + SkillsToolset = pydantic_ai_skills.SkillsToolset |
124 | 138 |
|
125 | 139 | directories, cleanup = _materialize_skills(self._sources) |
126 | 140 | self._cleanup = cleanup |
|
0 commit comments