Spaces:
Sleeping
Sleeping
| """κ³μΈ΅ λΆμ μμ² ν. | |
| 5λ¨κ³ μ€μ νΌ β ProcessorConfig λ§€ν β API νΈμΆ. | |
| """ | |
| import streamlit as st | |
| from core.api_client import ChainShiftClient | |
| # 17 Journey Types across 3 depth1 groups | |
| _JOURNEY_GROUPS: dict[str, list[tuple[str, str]]] = { | |
| "μΈμ§/λΉκ΅ (Awareness & Comparison)": [ | |
| ("verification", "μ¬μ€νμΈ"), | |
| ("market_trends", "μ΅μ νΈλ λ"), | |
| ("preparation", "μ€λΉ/νμ"), | |
| ("timing", "μκΈ°/νμ΄λ°"), | |
| ("review_experience", "리뷰/κ²½ν"), | |
| ("information_discovery", "μ 보νμ/κ°λ "), | |
| ("result_effectiveness", "ν¨κ³Ό/κ²°κ³Ό"), | |
| ("recommendation", "ꡬ맀μΆμ²"), | |
| ("comparison", "ꡬ맀μΆμ²(λΉκ΅)"), | |
| ("problem_solving", "λ¬Έμ ν΄κ²°"), | |
| ("difference_pros_cons", "μ°¨μ΄μ /μ₯λ¨μ "), | |
| ], | |
| "ꡬ맀 (Purchase)": [ | |
| ("pricing", "λΉμ©/κ°κ²©"), | |
| ("promotion_benefits", "νλ‘λͺ¨μ /ν μΈ/νν"), | |
| ("where_to_buy", "ꡬ맀μ²"), | |
| ], | |
| "ꡬ맀 ν (Post-Purchase)": [ | |
| ("howto", "μ ν/μλΉμ€ how-to"), | |
| ("refund_customer_service", "νλΆ A/S"), | |
| ("side_effect", "λΆμμ©"), | |
| ], | |
| } | |
| _PRODUCT_TYPES = ["product", "service", "brand"] | |
| _MODELS = ["gemini-3.1-pro-preview", "gemini-3-flash-preview", "gemini-2.5-pro", "gemini-2.5-flash"] | |
| _AGE_OPTIONS = ["10λ", "20λ", "30λ", "40λ", "50λ", "60λ μ΄μ"] | |
| _GENDER_OPTIONS = ["μ¬μ±", "λ¨μ±"] | |
| _TRAIT_OPTIONS = ["κ°μ±λΉμ€μ", "ν리미μμ νΈ", "νΈλ λλ―Όκ°", "μ€μ©μ£Όμ"] | |
| def render(base_ctx: dict): | |
| """λΆμ μμ² νΌ λ λλ§.""" | |
| st.markdown("##### π κ³μΈ΅ λΆμ μμ²") | |
| st.caption("ν€μλμ λΆμ 쑰건μ μ€μ νκ³ λΆμμ μμν©λλ€") | |
| if not base_ctx.get("api_key") and not base_ctx.get("access_token"): | |
| st.warning("μΈμ¦ μ λ³΄κ° μ€μ λμ§ μμμ΅λλ€.") | |
| return | |
| client = ChainShiftClient( | |
| api_key=base_ctx.get("api_key"), | |
| access_token=base_ctx.get("access_token"), | |
| ) | |
| # ββ Step 1: μ λ ₯ λΆμ ββ | |
| st.markdown("###### 1. μ λ ₯ λΆμ") | |
| col1, col2 = st.columns([3, 1]) | |
| with col1: | |
| raw_text = st.text_input( | |
| "λΆμ ν€μλ", | |
| key="hier:raw_text", | |
| placeholder="μ: κ°μμ§ μ¬λ£, μ¬ν κ°λ°©, μ κΈ°μ°¨ 보ν", | |
| ) | |
| with col2: | |
| product_type = st.selectbox( | |
| "μ ν μ ν", | |
| _PRODUCT_TYPES, | |
| key="hier:product_type", | |
| ) | |
| title = st.text_input( | |
| "λΆμ μ λͺ© (μ ν)", | |
| key="hier:title", | |
| placeholder="λΆμ κ²°κ³Ό ꡬλΆμ© μ λͺ©", | |
| ) | |
| # ββ Step 2: μ¬μ μ ν ββ | |
| st.markdown("---") | |
| st.markdown("###### 2. μλΉμ μ¬μ μ ν") | |
| st.caption("λΆμμ ν¬ν¨ν μ¬μ μ νμ μ ννμΈμ (κΈ°λ³Έ: ꡬ맀μΆμ²)") | |
| selected_journeys: list[str] = [] | |
| for group_label, types in _JOURNEY_GROUPS.items(): | |
| with st.expander(group_label, expanded=(group_label.startswith("μΈμ§"))): | |
| for code, label in types: | |
| default = code == "recommendation" | |
| if st.checkbox( | |
| label, | |
| value=default, | |
| key=f"hier:cej:{code}", | |
| ): | |
| selected_journeys.append(code) | |
| # ββ Step 3: νλ₯΄μλ (μ ν) ββ | |
| st.markdown("---") | |
| st.markdown("###### 3. νλ₯΄μλ μ€μ (μ ν)") | |
| use_persona = st.checkbox("νλ₯΄μλ μ μ©", key="hier:use_persona") | |
| persona_ages: list[str] = [] | |
| persona_gender: str | None = None | |
| persona_trait: str | None = None | |
| if use_persona: | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| persona_ages = st.multiselect("μ°λ Ήλ", _AGE_OPTIONS, key="hier:ages") | |
| with col2: | |
| gender_sel = st.selectbox( | |
| "μ±λ³", ["μ ν μν¨"] + _GENDER_OPTIONS, key="hier:gender", | |
| ) | |
| persona_gender = gender_sel if gender_sel != "μ ν μν¨" else None | |
| with col3: | |
| trait_sel = st.selectbox( | |
| "μλΉ μ±ν₯", ["μ ν μν¨"] + _TRAIT_OPTIONS, key="hier:trait", | |
| ) | |
| persona_trait = trait_sel if trait_sel != "μ ν μν¨" else None | |
| # ββ Step 4: λΈλλ 컨ν μ€νΈ (μ ν) ββ | |
| st.markdown("---") | |
| st.markdown("###### 4. λΈλλ 컨ν μ€νΈ (μ ν)") | |
| brand_mention = st.checkbox( | |
| "μ§λ¬Έμ λΈλλ ν¬ν¨", | |
| key="hier:brand_mention", | |
| help="νμ±ννλ©΄ μμ±λ μ§λ¬Έμ λΈλλλͺ μ΄ ν¬ν¨λ©λλ€", | |
| ) | |
| own_brands_input = "" | |
| if brand_mention: | |
| own_brands_input = st.text_input( | |
| "μμ¬ λΈλλ (μΌν ꡬλΆ)", | |
| key="hier:own_brands", | |
| placeholder="λΈλλA, λΈλλB", | |
| ) | |
| # ββ Step 5: λΆμ μ€μ ββ | |
| st.markdown("---") | |
| st.markdown("###### 5. λΆμ μ€μ ") | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| model = st.selectbox("AI λͺ¨λΈ", _MODELS, key="hier:model") | |
| with col2: | |
| questions_per_kw = st.number_input( | |
| "ν€μλλΉ μ§λ¬Έ μ", | |
| min_value=5, | |
| max_value=100, | |
| value=25, | |
| step=5, | |
| key="hier:qpk", | |
| ) | |
| with col3: | |
| max_nodes = st.number_input( | |
| "μ΅λ λ Έλ μ", | |
| min_value=10, | |
| max_value=500, | |
| value=100, | |
| step=10, | |
| key="hier:max_nodes", | |
| ) | |
| # ββ Submit ββ | |
| st.markdown("---") | |
| can_submit = bool(raw_text and raw_text.strip() and selected_journeys) | |
| if not raw_text or not raw_text.strip(): | |
| st.info("λΆμ ν€μλλ₯Ό μ λ ₯νμΈμ.") | |
| elif not selected_journeys: | |
| st.info("μ΅μ 1κ°μ μ¬μ μ νμ μ ννμΈμ.") | |
| if st.button( | |
| "βΆοΈ λΆμ μμ", | |
| type="primary", | |
| key="hier:submit", | |
| disabled=not can_submit, | |
| ): | |
| keyword = raw_text.strip() | |
| own_brands = [b.strip() for b in own_brands_input.split(",") if b.strip()] if own_brands_input else [] | |
| processor_config = { | |
| "version": "1.0", | |
| "inputAnalysis": { | |
| "rawText": keyword, | |
| "primaryKeyword": keyword, | |
| "productType": product_type, | |
| "locationCode": 2410, | |
| "languageCode": "ko", | |
| }, | |
| "brandContext": { | |
| "brandMention": brand_mention, | |
| "ownBrands": own_brands, | |
| }, | |
| "selectedJourneyTypes": selected_journeys, | |
| "persona": { | |
| "attributes": { | |
| "ages": persona_ages, | |
| "gender": persona_gender, | |
| "trait": persona_trait, | |
| }, | |
| }, | |
| "modifiers": [], | |
| } | |
| settings = { | |
| "model": model, | |
| "questionsPerKeyword": questions_per_kw, | |
| "maxNodes": max_nodes, | |
| "outputLanguage": "ko", | |
| } | |
| try: | |
| client.create_hierarchy_job( | |
| prompt=keyword, | |
| title=title.strip() if title else None, | |
| processor_config=processor_config, | |
| settings=settings, | |
| ) | |
| st.success("λΆμ Jobμ΄ μμ±λμμ΅λλ€! 'μ§ν νν©' νμμ νμΈνμΈμ.") | |
| st.rerun() | |
| except Exception as e: | |
| st.error(f"λΆμ μμ μ€ν¨: {e}") | |