@@ -62,7 +62,7 @@ from src.poc4.scenarios import ScenarioConfigError, load_demo_scenarios
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
MCP_PROTOCOL_VERSION = "2025-11-25"
|
||||
PREFERRED_TOOL = "ords.query.kb_select_ai_vpd"
|
||||
PREFERRED_TOOL = "oracle.select_ai.smilegate_game_text2sql"
|
||||
DEFAULT_QUESTION = ""
|
||||
MAX_RESPONSE_BYTES = 1_000_000
|
||||
MAX_CONVERSATION_MESSAGES = 8
|
||||
@@ -77,17 +77,21 @@ DEFAULT_QUERY_MODEL_PROFILE = "gpt54_mini_oci"
|
||||
ENV_FILE = ROOT / ".env"
|
||||
MCP_SERVERS_FILE = ROOT / "config" / "mcp_servers.json"
|
||||
VPD_TOKEN_PRESETS_FILE = ROOT / "config" / "vpd_token_presets.json"
|
||||
DEMO_SCENARIOS_FILE = ROOT / "config" / "hmm_demo_scenarios.json"
|
||||
DEMO_SCENARIOS_FILE = ROOT / "config" / "smilegate_demo_scenarios.json"
|
||||
APP_PROFILE_FILE = ROOT / "config" / "app_profile.json"
|
||||
CHAT_DB_FILE = ROOT / "data" / "poc4_mcp_chat.sqlite3"
|
||||
DEFAULT_VPD_USER_ID = "FC00789"
|
||||
VPD_OPERATIONS_URL = "https://kb.cloud-handson.com/"
|
||||
DEFAULT_VPD_USER_ID = "sg-teamlead"
|
||||
VPD_OPERATIONS_URL = "https://smilegate-backoffice.cloud-handson.com/"
|
||||
PORTAL_AUTHENTICATED_KEY = "poc4_portal_authenticated"
|
||||
PORTAL_AUTH_USER_KEY = "poc4_portal_auth_user"
|
||||
PORTAL_LOGIN_FAILURE_KEY = "poc4_portal_login_failed"
|
||||
PORTAL_REMEMBER_TOKEN_PARAM = "poc4_remember"
|
||||
PORTAL_REMEMBER_MAX_AGE_SECONDS = 7 * 24 * 60 * 60
|
||||
AUDIT_SCHEMA = "POC_2"
|
||||
AUDIT_SCHEMA = "SGMP_POC"
|
||||
REFERENCE_EVIDENCE_ENABLED = (
|
||||
os.environ.get("POC4_REFERENCE_EVIDENCE_ENABLED", "").strip().lower()
|
||||
in {"1", "true", "yes"}
|
||||
)
|
||||
AUDIT_DB_ENV_FILE = Path(
|
||||
os.environ.get("POC4_AUDIT_DB_ENV_FILE", "/home/opc/kbmcp/.env")
|
||||
).expanduser()
|
||||
@@ -2374,6 +2378,8 @@ def collect_security_evidence(
|
||||
) -> Mapping[str, Any]:
|
||||
"""Collect predefined, token-scoped security evidence without exposing secrets."""
|
||||
|
||||
if not REFERENCE_EVIDENCE_ENABLED:
|
||||
return {}
|
||||
kind = _security_evidence_kind(question)
|
||||
if not kind or token_preset is None:
|
||||
return {}
|
||||
@@ -2938,6 +2944,8 @@ def collect_business_evidence(
|
||||
) -> Mapping[str, Any]:
|
||||
"""Collect token-validated, explicitly scoped business and catalog evidence."""
|
||||
|
||||
if not REFERENCE_EVIDENCE_ENABLED:
|
||||
return {}
|
||||
kind = _business_evidence_kind(question)
|
||||
if not kind or token_preset is None:
|
||||
return {}
|
||||
@@ -7069,8 +7077,8 @@ def main() -> None:
|
||||
else:
|
||||
selected_token_preset = None
|
||||
if configured_mcp_bearer:
|
||||
# The HMM MCP gateway uses its own server-side credential. VPD user
|
||||
# tokens remain UI context only and must never be forwarded to it.
|
||||
# The Smilegate MCP gateway uses a server-side credential. UI-only
|
||||
# context must never be forwarded as a second bearer token.
|
||||
st.caption("MCP 인증: 서버 관리 토큰 적용")
|
||||
manual_bearer_token = ""
|
||||
elif selected_token_preset is not None:
|
||||
@@ -7256,9 +7264,7 @@ def main() -> None:
|
||||
'<div id="kb-main-tabs-anchor" style="scroll-margin-top: 0.75rem;"></div>',
|
||||
unsafe_allow_html=True,
|
||||
)
|
||||
architecture_tab, scenario_tab, audit_tab, operations_tab = st.tabs(
|
||||
["아키텍처", "시나리오", "감사로그", "보안관리"]
|
||||
)
|
||||
architecture_tab, scenario_tab = st.tabs(["아키텍처", "시나리오"])
|
||||
with architecture_tab:
|
||||
_render_architecture_tab()
|
||||
|
||||
@@ -7359,12 +7365,6 @@ def main() -> None:
|
||||
height=0,
|
||||
)
|
||||
|
||||
with audit_tab:
|
||||
_render_fga_audit_tab()
|
||||
|
||||
with operations_tab:
|
||||
_render_vpd_operations_tab()
|
||||
|
||||
if not submitted:
|
||||
return
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"version": 1,
|
||||
"product": {
|
||||
"name": "AI 업무 에이전트",
|
||||
"short_name": "AGENT",
|
||||
"page_title": "AI 업무 에이전트",
|
||||
"name": "SMILEGATE DATA & AI POC",
|
||||
"short_name": "SMILEGATE",
|
||||
"page_title": "SMILEGATE DATA & AI POC",
|
||||
"page_icon": "🤖",
|
||||
"header_title": "AI 업무 에이전트",
|
||||
"header_description": "사용자 권한에 맞는 업무 질의와 보안 관리 기능을 제공합니다.",
|
||||
"login_kicker": "DATA & AI DEMO",
|
||||
"login_title": "AI 업무 에이전트",
|
||||
"login_description": "사용자 인증 후 업무 질의와 보안 관리 기능을 이용할 수 있습니다.",
|
||||
"login_footer": "인증된 DEMO 사용자만 접근할 수 있습니다."
|
||||
"header_title": "스마일게이트 게임 데이터 AI 에이전트",
|
||||
"header_description": "게임 로그·서비스 데이터를 기반으로 AI 업무 효율화와 데이터 플랫폼 활용 방식을 검증합니다.",
|
||||
"login_kicker": "SMILEGATE DATA & AI POC",
|
||||
"login_title": "스마일게이트 게임 데이터 AI 에이전트",
|
||||
"login_description": "사용자 인증 후 게임 데이터 AI 질의와 보안 관리 기능을 이용할 수 있습니다.",
|
||||
"login_footer": "승인된 Data & AI PoC 사용자만 접근할 수 있습니다."
|
||||
},
|
||||
"theme": {
|
||||
"primary_color": "#003b70",
|
||||
"text_color": "#172b3a",
|
||||
"muted_color": "#667785",
|
||||
"border_color": "#dfe7ed"
|
||||
"primary_color": "#113F67",
|
||||
"text_color": "#15283B",
|
||||
"muted_color": "#5D6C7C",
|
||||
"border_color": "#D7E0E8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
{
|
||||
"default_server_id": "hmm_hr_mcp",
|
||||
"default_server_id": "smilegate_game_data_mcp",
|
||||
"servers": [
|
||||
{
|
||||
"id": "hmm_hr_mcp",
|
||||
"id": "smilegate_game_data_mcp",
|
||||
"enabled": true,
|
||||
"provider": "hmm_compat_mcp",
|
||||
"provider": "smilegate_select_ai_mcp",
|
||||
"transport": "http",
|
||||
"endpoint_url": "https://hmm-mcp.cloud-handson.com/mcp",
|
||||
"auth_token_env": "HMM_MCP_BEARER_TOKEN",
|
||||
"endpoint_url": "https://smilegate-backoffice.cloud-handson.com/mcp",
|
||||
"auth_token_env": "SMILEGATE_MCP_BEARER_TOKEN",
|
||||
"timeout_seconds_env": "POC3_MCP_TIMEOUT_SECONDS",
|
||||
"default_tool": "search_hr_data",
|
||||
"default_tool": "oracle.select_ai.smilegate_game_text2sql",
|
||||
"router_model_profile": "gpt54_mini_oci",
|
||||
"tool_allowlist": [
|
||||
"search_hr_data",
|
||||
"resolve_hr_term",
|
||||
"search_hr_policy"
|
||||
"oracle.select_ai.smilegate_game_text2sql"
|
||||
],
|
||||
"description": "HMM HR knowledge and data MCP server"
|
||||
"description": "Smilegate game-data Text2SQL MCP server"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"version": 1,
|
||||
"description": "Smilegate Data & AI PoC 화면에 표시할 게임 데이터 질의 샘플입니다.",
|
||||
"scenarios": [
|
||||
{
|
||||
"id": "GAME-01",
|
||||
"enabled": true,
|
||||
"category": "활성 사용자",
|
||||
"title": "카제나 최신 AU",
|
||||
"question": "카제나 최신 기준 활성 사용자 수(AU)를 알려줘"
|
||||
},
|
||||
{
|
||||
"id": "GAME-02",
|
||||
"enabled": true,
|
||||
"category": "매출",
|
||||
"title": "게임별 판매 현황",
|
||||
"question": "최신 기준 게임별 판매 건수와 판매 금액을 보여줘"
|
||||
},
|
||||
{
|
||||
"id": "GAME-03",
|
||||
"enabled": true,
|
||||
"category": "환불",
|
||||
"title": "최근 환불 현황",
|
||||
"question": "최신 기준 게임별 환불 건수와 환불 금액을 보여줘"
|
||||
},
|
||||
{
|
||||
"id": "GAME-04",
|
||||
"enabled": true,
|
||||
"category": "게임·서버",
|
||||
"title": "게임 서버 구성",
|
||||
"question": "등록된 게임과 게임 서버 정보를 보여줘"
|
||||
},
|
||||
{
|
||||
"id": "GAME-05",
|
||||
"enabled": true,
|
||||
"category": "사용자 분석",
|
||||
"title": "신규 사용자 현황",
|
||||
"question": "최신 월 기준 게임별 신규 사용자 수를 보여줘"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"presets": [
|
||||
{
|
||||
"enabled": true,
|
||||
"enabled": false,
|
||||
"default": true,
|
||||
"token": "vpd_live_REPLACE_WITH_USER_TOKEN",
|
||||
"user_id": "FC00789",
|
||||
|
||||
@@ -16,29 +16,29 @@ class DemoScenarioConfigTest(unittest.TestCase):
|
||||
with patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"AGENT_CONSOLE_SHORT_NAME": "HMM",
|
||||
"AGENT_CONSOLE_PAGE_TITLE": "HMM AI 업무 에이전트",
|
||||
"AGENT_CONSOLE_PRIMARY_COLOR": "#003b70",
|
||||
"AGENT_CONSOLE_SHORT_NAME": "SMILEGATE",
|
||||
"AGENT_CONSOLE_PAGE_TITLE": "SMILEGATE DATA & AI POC",
|
||||
"AGENT_CONSOLE_PRIMARY_COLOR": "#113F67",
|
||||
},
|
||||
clear=False,
|
||||
):
|
||||
profile = load_app_profile(path)
|
||||
|
||||
self.assertEqual(profile.short_name, "HMM")
|
||||
self.assertEqual(profile.page_title, "HMM AI 업무 에이전트")
|
||||
self.assertEqual(profile.primary_color, "#003b70")
|
||||
self.assertEqual(profile.short_name, "SMILEGATE")
|
||||
self.assertEqual(profile.page_title, "SMILEGATE DATA & AI POC")
|
||||
self.assertEqual(profile.primary_color, "#113F67")
|
||||
|
||||
def test_profile_reads_dotenv_values(self) -> None:
|
||||
path = Path(__file__).parents[1] / "config" / "app_profile.json"
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
env_file = Path(temp_dir) / ".env"
|
||||
env_file.write_text("AGENT_CONSOLE_SHORT_NAME=HMM\n", encoding="utf-8")
|
||||
env_file.write_text("AGENT_CONSOLE_SHORT_NAME=SMILEGATE\n", encoding="utf-8")
|
||||
profile = load_app_profile(path, env_file)
|
||||
|
||||
self.assertEqual(profile.short_name, "HMM")
|
||||
self.assertEqual(profile.short_name, "SMILEGATE")
|
||||
|
||||
def test_hmm_scenarios_are_enabled_and_unique(self) -> None:
|
||||
path = Path(__file__).parents[1] / "config" / "hmm_demo_scenarios.json"
|
||||
def test_smilegate_scenarios_are_enabled_and_unique(self) -> None:
|
||||
path = Path(__file__).parents[1] / "config" / "smilegate_demo_scenarios.json"
|
||||
scenarios = load_demo_scenarios(path)
|
||||
|
||||
self.assertGreaterEqual(len(scenarios), 3)
|
||||
|
||||
Reference in New Issue
Block a user