62 lines
2.0 KiB
Python
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
|