Ask GPT-5 Nano to classify a single device. Returns a device_type string or None.
(ai_service, vendor, ports, hostname, mac)
| 801 | |
| 802 | |
| 803 | def _ask_ai_classify(ai_service, vendor, ports, hostname, mac): |
| 804 | """Ask GPT-5.4 Nano to classify a single device. Returns a device_type string or None.""" |
| 805 | if not ai_service or not ai_service.ensure_ready(): |
| 806 | return None |
| 807 | |
| 808 | valid_types = ", ".join(sorted(VALID_DEVICE_TYPES - {"ragnar", "unknown"})) |
| 809 | |
| 810 | system = ( |
| 811 | "You are a network device classifier. Given device metadata, reply with ONLY " |
| 812 | "the device_type string — one of: " + valid_types + ". " |
| 813 | "Reply with just the single word. If uncertain, reply unknown." |
| 814 | ) |
| 815 | |
| 816 | user = ( |
| 817 | f"MAC vendor: {vendor or 'unknown'}\n" |
| 818 | f"Hostname: {hostname or 'unknown'}\n" |
| 819 | f"MAC: {mac or 'unknown'}\n" |
| 820 | f"Open ports: {', '.join(str(p) for p in (ports or [])[:20]) or 'none'}\n" |
| 821 | f"Classify this device." |
| 822 | ) |
| 823 | |
| 824 | # Use GPT-5.4 Nano for fast/cheap classification |
| 825 | original_model = ai_service.model |
| 826 | try: |
| 827 | ai_service.model = "gpt-5.4-nano" |
| 828 | answer = ai_service._ask(system, user) |
| 829 | finally: |
| 830 | ai_service.model = original_model |
| 831 | |
| 832 | if not answer: |
| 833 | return None |
| 834 | |
| 835 | # Sanitise — model should return just the type string |
| 836 | answer = answer.strip().lower().replace(" ", "_") |
| 837 | # Remove any surrounding quotes or punctuation |
| 838 | answer = answer.strip('"\'.,') |
| 839 | return answer if answer in VALID_DEVICE_TYPES else None |
no test coverage detected