auto_agent/backend/app/services/intent_service.py

62 lines
2.0 KiB
Python

from __future__ import annotations
import re
from app.core.constants import ACTION_TYPE_DEPLOY
class IntentService:
ENV_MAPPING = {
"测试环境": "test",
"测试": "test",
"test": "test",
"预发环境": "staging",
"预发": "staging",
"staging": "staging",
"生产环境": "prod",
"生产": "prod",
"prod": "prod",
}
def parse(self, input_text: str) -> tuple[dict[str, str | None], list[str]]:
parsed_intent: dict[str, str | None] = {
"action_type": ACTION_TYPE_DEPLOY if self._is_deploy(input_text) else None,
"app_code": self._extract_app_code(input_text),
"env": self._extract_env(input_text),
"version": self._extract_version(input_text),
}
missing_slots = [
slot_name
for slot_name, value in parsed_intent.items()
if slot_name in {"action_type", "app_code", "env", "version"} and not value
]
return parsed_intent, missing_slots
def _is_deploy(self, input_text: str) -> bool:
lowered = input_text.lower()
return "部署" in input_text or "deploy" in lowered
def _extract_app_code(self, input_text: str) -> str | None:
patterns = [
r"\s*([A-Za-z0-9_-]+)",
r"deploy\s+([A-Za-z0-9_-]+)",
r"\b([A-Za-z0-9_-]+-service)\b",
]
for pattern in patterns:
match = re.search(pattern, input_text, re.IGNORECASE)
if match:
return match.group(1)
return None
def _extract_env(self, input_text: str) -> str | None:
lowered = input_text.lower()
for key, value in self.ENV_MAPPING.items():
if key.lower() in lowered:
return value
return None
def _extract_version(self, input_text: str) -> str | None:
match = re.search(r"\b\d+\.\d+\.\d+(?:[-._A-Za-z0-9]+)?\b", input_text)
return match.group(0) if match else None