| from __future__ import annotations |
| """ |
| ์๋๋ฆฌ์ค ์นดํ๋ก๊ทธ ์๋ (Intent / Action / Behavior) |
| |
| ๋ฑ๋ก๋ ๋ชจ๋ ์๋๋ฆฌ์ค(available_scenarios)๋ฅผ catalog_* ํ
์ด๋ธ์ scenario_id์ ํจ๊ป ์ ์ฌํ๋ค. |
| โ AdminPage๊ฐ ์๋๋ฆฌ์ค๋ณ ์นดํ๋ก๊ทธ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์กฐํํ ์ ์๊ฒ ํ๋ค. |
| """ |
| import json |
| import logging |
|
|
| from config import settings |
| from data.executor import get_executor, DuckDBExecutor |
| from core.engines import config, available_scenarios |
|
|
| logger = logging.getLogger(__name__) |
|
|
| |
| _SCENARIO_NAMES = { |
| "cs-myk-v3": "๋ง์ดK CS ์๋ด ์์ฐ", |
| "bundle-v3": "๊ฒฐํฉ ์ํ ์ถ์ฒ ์์ฐ", |
| "worker-v3": "์ง์ฅ์ธ ๋ผ์ดํ์ผ์ด ์์ฐ", |
| } |
|
|
|
|
| def seed_catalogs() -> None: |
| """๋ฑ๋ก๋ ๋ชจ๋ ์๋๋ฆฌ์ค์ ์นดํ๋ก๊ทธ๋ฅผ ์ ์ฌํ๋ค. |
| |
| catalog_intentsยทcatalog_actionsยทcatalog_behaviors๋ฅผ ๋น์ด ๋ค |
| available_scenarios()์ ๋ชจ๋ ์๋๋ฆฌ์ค๋ฅผ ๋ค์ ์ ์ฌํ๋ค(์ ์ฒด ๊ต์ฒด). |
| """ |
| ex = get_executor() |
| for tbl in ("catalog_intents", "catalog_actions", "catalog_behaviors"): |
| ex.execute(f"DELETE FROM {tbl}") |
| for sid in available_scenarios(): |
| _seed_one(ex, sid) |
|
|
|
|
| def _seed_one(ex: DuckDBExecutor, scenario_id: str) -> None: |
| """ํ ์๋๋ฆฌ์ค์ ์นดํ๋ก๊ทธ๋ฅผ catalog_* ํ
์ด๋ธ์ ์ ์ฌํ๋ค. |
| |
| ์๋๋ฆฌ์ค ๋ฉํ(scenarios)์ IntentยทActionยทBehavior ์นดํ๋ก๊ทธ๋ฅผ ์ ์ฌํ๋ค. |
| Action์ Intent-ํค 3์ฑ๋ ๊ตฌ์กฐ(dict)์ ๊ตฌ๋ฒ์ ๋ฆฌ์คํธ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ๊ณ , |
| Behavior๋ tree-2stepยทsingle-selectยท๊ตฌ๋ฒ์ steps ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํ๋ค. |
| |
| Args: |
| ex: ์นดํ๋ก๊ทธ๋ฅผ ์ ์ฌํ DuckDB executor. |
| scenario_id: ์ ์ฌํ ์๋๋ฆฌ์ค ID. |
| """ |
| |
| taxonomy = config.get_taxonomy(scenario_id) |
| description = config.load_layer(scenario_id, "input").get("description", "") |
| ex.execute( |
| "INSERT OR REPLACE INTO scenarios (id, name, version, description) VALUES (?, ?, ?, ?)", |
| [ |
| scenario_id, |
| _SCENARIO_NAMES.get(scenario_id, scenario_id), |
| taxonomy.get("version", ""), |
| description, |
| ], |
| ) |
|
|
| |
| rows = [ |
| [ |
| scenario_id, |
| i["id"], i["name"], |
| i["L1_id"], i["L1_name"], |
| i["L2_id"], i["L2_name"], |
| i["inference_type"], |
| json.dumps(i.get("features", []), ensure_ascii=False), |
| ] |
| for i in taxonomy["intents"] |
| ] |
| ex.executemany( |
| "INSERT INTO catalog_intents " |
| "(scenario_id, intent_id, intent_name, L1_id, L1_name, L2_id, L2_name, inference_type, features_json) " |
| "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", |
| rows, |
| ) |
|
|
| |
| actions_data = config.get_actions(scenario_id) |
| a_rows: list[list] = [] |
| raw_actions = actions_data["actions"] |
| if isinstance(raw_actions, dict): |
| |
| for intent_id, ch_map in raw_actions.items(): |
| for channel, body in ch_map.items(): |
| if isinstance(body, dict): |
| message = f"์ํฉ: {body.get('situation', '')} / ์๋ด: {body.get('guidance', '')}" |
| else: |
| message = str(body) |
| a_rows.append([ |
| scenario_id, |
| f"{intent_id}#{channel}", channel, |
| json.dumps([intent_id], ensure_ascii=False), |
| "", channel, message, |
| ]) |
| else: |
| |
| for a in raw_actions: |
| a_rows.append([ |
| scenario_id, |
| a["id"], a["name"], |
| json.dumps(a.get("intents", []), ensure_ascii=False), |
| a.get("condition", ""), a["channel"], a.get("message", ""), |
| ]) |
| ex.executemany( |
| "INSERT INTO catalog_actions " |
| "(scenario_id, action_id, action_name, intents_json, condition, channel, message) " |
| "VALUES (?, ?, ?, ?, ?, ?, ?)", |
| a_rows, |
| ) |
|
|
| |
| behaviors_data = config.get_behaviors(scenario_id) |
| b_rows: list[list] = [] |
| structure = behaviors_data.get("structure") |
| if structure == "tree-2step": |
| |
| for b in behaviors_data["step1"]["behaviors"]: |
| b_rows.append([scenario_id, b["id"], 1, b["name"], b["event_type"], b["entity"]]) |
| for parent_id, items in behaviors_data["step2"]["by_parent"].items(): |
| for b in items: |
| b_rows.append([scenario_id, b["id"], 2, b["name"], b["event_type"], b["entity"]]) |
| for b in behaviors_data["step2"]["common"]: |
| b_rows.append([scenario_id, b["id"], 2, b["name"], b["event_type"], b["entity"]]) |
| elif structure == "single-select": |
| |
| for b in behaviors_data["apps"]: |
| b_rows.append([scenario_id, b["id"], 1, b["name"], b["event_type"], b["entity"]]) |
| else: |
| |
| for step_block in behaviors_data["steps"]: |
| step = step_block["step"] |
| for b in step_block["behaviors"]: |
| b_rows.append([scenario_id, b["id"], step, b["name"], b["event_type"], b["entity"]]) |
| ex.executemany( |
| "INSERT INTO catalog_behaviors " |
| "(scenario_id, behavior_id, step, behavior_name, event_type, entity) " |
| "VALUES (?, ?, ?, ?, ?, ?)", |
| b_rows, |
| ) |
|
|
| logger.info( |
| f"Seeded catalog [{scenario_id}]: intents={len(rows)} actions={len(a_rows)} behaviors={len(b_rows)}" |
| ) |
|
|
|
|
| def load_intents_catalog(scenario_id: str = settings.SCENARIO_ID) -> list[dict]: |
| """์๋๋ฆฌ์ค๋ณ Intent ์นดํ๋ก๊ทธ๋ฅผ ์กฐํํ๋ค. |
| |
| Args: |
| scenario_id: ์กฐํํ ์๋๋ฆฌ์ค ID (๊ธฐ๋ณธ๊ฐ์ settings.SCENARIO_ID). |
| |
| Returns: |
| Intent ์ ์ dict์ ๋ชฉ๋ก (idยทnameยท๊ณ์ธตยทinference_typeยทfeatures ํฌํจ). |
| """ |
| ex = get_executor() |
| df = ex.to_pandas( |
| "SELECT intent_id, intent_name, L1_id, L1_name, L2_id, L2_name, inference_type, features_json " |
| "FROM catalog_intents WHERE scenario_id = ?", |
| [scenario_id], |
| ) |
| rows = [] |
| for _, r in df.iterrows(): |
| rows.append({ |
| "id": r["intent_id"], |
| "name": r["intent_name"], |
| "L1_id": r["L1_id"], |
| "L1_name": r["L1_name"], |
| "L2_id": r["L2_id"], |
| "L2_name": r["L2_name"], |
| "inference_type": r["inference_type"], |
| "features": json.loads(r["features_json"]) if r["features_json"] else [], |
| }) |
| return rows |
|
|
|
|
| def load_behaviors_catalog(scenario_id: str = settings.SCENARIO_ID) -> dict[str, dict]: |
| """์๋๋ฆฌ์ค๋ณ Behavior ์นดํ๋ก๊ทธ๋ฅผ ์กฐํํ๋ค. |
| |
| Args: |
| scenario_id: ์กฐํํ ์๋๋ฆฌ์ค ID (๊ธฐ๋ณธ๊ฐ์ settings.SCENARIO_ID). |
| |
| Returns: |
| behavior_id๋ฅผ ํค๋ก ํ๊ณ stepยทnameยทevent_typeยทentity๋ฅผ ๋ด์ dict๋ฅผ |
| ๊ฐ์ผ๋ก ๊ฐ์ง๋ ๋งคํ. |
| """ |
| ex = get_executor() |
| df = ex.to_pandas( |
| "SELECT behavior_id, step, behavior_name, event_type, entity " |
| "FROM catalog_behaviors WHERE scenario_id = ?", |
| [scenario_id], |
| ) |
| result = {} |
| for _, r in df.iterrows(): |
| result[r["behavior_id"]] = { |
| "step": int(r["step"]), |
| "name": r["behavior_name"], |
| "event_type": r["event_type"], |
| "entity": r["entity"], |
| } |
| return result |
|
|