|
15 | 15 | from typing import Any |
16 | 16 |
|
17 | 17 | from hexdag.kernel.pipeline_builder.tag_discovery import discover_tags, get_tag_schema |
| 18 | +from hexdag.kernel.ports.detection import detect_port_type as detect_port_type |
18 | 19 | from hexdag.kernel.resolver import get_builtin_aliases, resolve |
19 | 20 | from hexdag.kernel.schema import SchemaGenerator |
20 | 21 |
|
@@ -266,89 +267,6 @@ def list_adapters(port_type: str | None = None) -> list[dict[str, Any]]: |
266 | 267 | return sorted(unique_adapters, key=lambda x: (x["port_type"], x["name"])) |
267 | 268 |
|
268 | 269 |
|
269 | | -def detect_port_type(adapter_class: type) -> str: |
270 | | - """Detect port type from adapter class using protocol inspection. |
271 | | -
|
272 | | - Adapters MUST inherit from their port protocol to be properly detected. |
273 | | - This is a convention enforced by hexDAG - no name-based guessing. |
274 | | -
|
275 | | - Port Protocol Convention |
276 | | - ------------------------ |
277 | | - All adapters must inherit from their corresponding port protocol: |
278 | | -
|
279 | | - - LLM adapters: inherit from `LLM`, `SupportsGeneration`, `SupportsFunctionCalling`, etc. |
280 | | - - Memory adapters: inherit from `Memory` |
281 | | - - Database adapters: inherit from `Database` or `SQLAdapter` |
282 | | - - Secret adapters: inherit from `SecretStore` |
283 | | - - Storage adapters: inherit from `FileStorage` or `VectorStorePort` |
284 | | - - Tool adapters: inherit from `ToolRouter` |
285 | | -
|
286 | | - Example:: |
287 | | -
|
288 | | - from hexdag.kernel.ports.llm import LLM |
289 | | -
|
290 | | - class MyCustomLLMAdapter(LLM): |
291 | | - async def aresponse(self, messages): |
292 | | - ... |
293 | | -
|
294 | | - Parameters |
295 | | - ---------- |
296 | | - adapter_class : type |
297 | | - The adapter class to inspect |
298 | | -
|
299 | | - Returns |
300 | | - ------- |
301 | | - str |
302 | | - Port type: "llm", "memory", "database", "secret", "storage", "tool_router", or "unknown" |
303 | | -
|
304 | | - Examples |
305 | | - -------- |
306 | | - >>> from hexdag.stdlib.adapters.openai import OpenAIAdapter |
307 | | - >>> detect_port_type(OpenAIAdapter) |
308 | | - 'llm' |
309 | | - """ |
310 | | - # Check explicit decorator metadata first (future @adapter decorator) |
311 | | - explicit_port = getattr(adapter_class, "_hexdag_implements_port", None) |
312 | | - if explicit_port: |
313 | | - return str(explicit_port) |
314 | | - |
315 | | - # Check protocol inheritance (required convention) |
316 | | - mro_names = [c.__name__ for c in adapter_class.__mro__] |
317 | | - |
318 | | - # LLM adapters implement LLM, SupportsGeneration, SupportsFunctionCalling, etc. |
319 | | - llm_protocols = {"LLM", "SupportsGeneration", "SupportsFunctionCalling", "SupportsVision"} |
320 | | - if any(name in mro_names for name in llm_protocols): |
321 | | - return "llm" |
322 | | - |
323 | | - # Memory adapters implement Memory protocol |
324 | | - if "Memory" in mro_names: |
325 | | - return "memory" |
326 | | - |
327 | | - # Database adapters implement Database or SQLAdapter |
328 | | - if "Database" in mro_names or "DatabasePort" in mro_names or "SQLAdapter" in mro_names: |
329 | | - return "database" |
330 | | - |
331 | | - # Secret adapters implement SecretStore |
332 | | - if "SecretStore" in mro_names or "SecretPort" in mro_names: |
333 | | - return "secret" |
334 | | - |
335 | | - # Storage adapters implement FileStorage or VectorStorePort |
336 | | - storage_ports = ("FileStorage", "FileStoragePort", "VectorStorePort") |
337 | | - if any(name in mro_names for name in storage_ports): |
338 | | - return "storage" |
339 | | - |
340 | | - # DataStore adapters implement DataStore |
341 | | - if "DataStore" in mro_names: |
342 | | - return "data_store" |
343 | | - |
344 | | - # Tool router adapters implement ToolRouter |
345 | | - if "ToolRouter" in mro_names: |
346 | | - return "tool_router" |
347 | | - |
348 | | - # No fallback - adapters must follow the convention |
349 | | - return "unknown" |
350 | | - |
351 | | - |
352 | 270 | def _discover_entities( |
353 | 271 | discover_fn: Any, |
354 | 272 | builtin_modules: list[str], |
|
0 commit comments