Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| import sys | |
| import importlib.util | |
| from pathlib import Path | |
| import dotenv | |
| dotenv.load_dotenv() | |
| # ํ์ฌ ๋๋ ํ ๋ฆฌ ์ค์ | |
| current_dir = Path(__file__).parent | |
| # ๊ฐ ๊ธฐ๋ฅ๋ณ ๋ชจ๋ ๋ก๋ ํจ์ | |
| def load_module_from_path(module_name, file_path): | |
| """๋์ ์ผ๋ก ๋ชจ๋์ ๋ก๋ํ๋ ํจ์""" | |
| try: | |
| spec = importlib.util.spec_from_file_location(module_name, file_path) | |
| module = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(module) | |
| return module | |
| except Exception as e: | |
| print(f"๋ชจ๋ ๋ก๋ ์คํจ {module_name}: {e}") | |
| return None | |
| # ๊ฐ ๊ธฐ๋ฅ๋ณ ๋ชจ๋ ๋ฐ ํจ์ ๋ก๋ | |
| modules = {} | |
| available_features = {} | |
| # 1. commonly-asked-question | |
| try: | |
| llm_functions_path = current_dir / "commonly-asked-question" / "llm_functions.py" | |
| if llm_functions_path.exists(): | |
| modules['commonly_asked'] = load_module_from_path("commonly_asked_llm", llm_functions_path) | |
| available_features['commonly_asked'] = modules['commonly_asked'] is not None | |
| else: | |
| available_features['commonly_asked'] = False | |
| except Exception as e: | |
| print(f"commonly-asked-question ๋ชจ๋ ๋ก๋ ์คํจ: {e}") | |
| available_features['commonly_asked'] = False | |
| # 2. question-recommendation | |
| try: | |
| llm_functions_path = current_dir / "question-recommendation" / "llm_functions.py" | |
| if llm_functions_path.exists(): | |
| modules['question_rec'] = load_module_from_path("question_rec_llm", llm_functions_path) | |
| available_features['question_rec'] = modules['question_rec'] is not None | |
| else: | |
| available_features['question_rec'] = False | |
| except Exception as e: | |
| print(f"question-recommendation ๋ชจ๋ ๋ก๋ ์คํจ: {e}") | |
| available_features['question_rec'] = False | |
| # 3. jd-recommendation | |
| try: | |
| llm_functions_path = current_dir / "jd-recommendation" / "llm_functions.py" | |
| if llm_functions_path.exists(): | |
| modules['jd_rec'] = load_module_from_path("jd_rec_llm", llm_functions_path) | |
| available_features['jd_rec'] = modules['jd_rec'] is not None | |
| else: | |
| available_features['jd_rec'] = False | |
| except Exception as e: | |
| print(f"jd-recommendation ๋ชจ๋ ๋ก๋ ์คํจ: {e}") | |
| available_features['jd_rec'] = False | |
| # 4. industry-classification | |
| try: | |
| llm_functions_path = current_dir / "industry-classification" / "llm_functions.py" | |
| if llm_functions_path.exists(): | |
| modules['industry'] = load_module_from_path("industry_llm", llm_functions_path) | |
| available_features['industry'] = modules['industry'] is not None | |
| else: | |
| available_features['industry'] = False | |
| except Exception as e: | |
| print(f"industry-classification ๋ชจ๋ ๋ก๋ ์คํจ: {e}") | |
| available_features['industry'] = False | |
| # 5. jasoseo-context-report | |
| try: | |
| llm_functions_path = current_dir / "jasoseo-context-report" / "llm_functions.py" | |
| if llm_functions_path.exists(): | |
| modules['jasoseo'] = load_module_from_path("jasoseo_llm", llm_functions_path) | |
| available_features['jasoseo'] = modules['jasoseo'] is not None | |
| else: | |
| available_features['jasoseo'] = False | |
| except Exception as e: | |
| print(f"jasoseo-context-report ๋ชจ๋ ๋ก๋ ์คํจ: {e}") | |
| available_features['jasoseo'] = False | |
| # 6. company-size-classification | |
| try: | |
| llm_functions_path = current_dir / "company-size-classification" / "llm_functions.py" | |
| if llm_functions_path.exists(): | |
| modules['company_size'] = load_module_from_path("company_size_llm", llm_functions_path) | |
| available_features['company_size'] = modules['company_size'] is not None | |
| else: | |
| available_features['company_size'] = False | |
| except Exception as e: | |
| print(f"company-size-classification ๋ชจ๋ ๋ก๋ ์คํจ: {e}") | |
| available_features['company_size'] = False | |
| # OpenAI ๊ด๋ จ ๋ชจ๋ | |
| try: | |
| from openai import OpenAI | |
| import yaml | |
| openai_available = True | |
| except ImportError: | |
| openai_available = False | |
| # OpenAI ํด๋ผ์ด์ธํธ ์ด๊ธฐํ | |
| client = None | |
| if openai_available and os.getenv("OPENAI_API_KEY"): | |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| # ๊ณตํต CSS ์คํ์ผ | |
| common_css = """ | |
| .main-header { | |
| text-align: center; | |
| padding: 20px; | |
| background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| border-radius: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .input-section { | |
| background-color: #f8f9fa; | |
| padding: 20px; | |
| border-radius: 8px; | |
| margin: 10px 0; | |
| } | |
| .example-section { | |
| background-color: #f0f9ff; | |
| padding: 15px; | |
| border-radius: 8px; | |
| margin: 10px 0; | |
| } | |
| .tab-container { | |
| margin: 20px 0; | |
| height: 100%; | |
| } | |
| """ | |
| # ์์ ๋ฐ์ดํฐ | |
| example_companies = ["์ผ์ฑ์ ์", "ํ ์ค", "์นด์นด์ค", "๋ค์ด๋ฒ", "LG์ ์", "ํ๋์๋์ฐจ", "CJ์ ์ผ์ ๋น", "ํ์ด๋ธ", "์ฟ ํก", "๋ฐฐ๋ฌ์๋ฏผ์กฑ", "์ ํ์ํ", "SKT", "ํฌ์ค์ฝ", "ํ๋๊ฑด์ค", "์๋ชจ๋ ํผ์ํฝ"] | |
| example_jobs = ["๋ฐฑ์๋ ๊ฐ๋ฐ", "ํ๋ก ํธ์๋ ๊ฐ๋ฐ", "๋ฐ์ดํฐ ์ฌ์ด์ธํฐ์คํธ", "๋ง์ผํ ", "์์ ", "๊ธฐํ", "๋์์ธ", "HR", "์ฌ๋ฌด", "A&R", "๊ฒฝ์๊ธฐํ", "ํด์ธ์์ ", "์จ๋ผ์ธ๋ง์ผํ ", "์ํ๋ง์ผํ ", "HRM(์ธ์ฌ์ด์)"] | |
| experience_levels = ["์ ์ ", "๊ฒฝ๋ ฅ", "์ธํด", "๊ธฐํ"] | |
| # ๊ณตํต ํจ์๋ค | |
| def create_example_buttons(companies, jobs, company_input, job_input): | |
| """์์ ๋ฒํผ๋ค์ ์์ฑํ๋ ํจ์""" | |
| gr.Markdown("### ๐ก **์์ ํ์ฌ**") | |
| with gr.Row(): | |
| for company in companies[:5]: | |
| btn = gr.Button(company, size="sm", variant="secondary") | |
| btn.click(fn=lambda x=company: x, outputs=company_input) | |
| with gr.Row(): | |
| for company in companies[5:10]: | |
| btn = gr.Button(company, size="sm", variant="secondary") | |
| btn.click(fn=lambda x=company: x, outputs=company_input) | |
| gr.Markdown("### ๐ผ **์์ ์ง๋ฌด**") | |
| with gr.Row(): | |
| for job in jobs[:5]: | |
| btn = gr.Button(job, size="sm", variant="secondary") | |
| btn.click(fn=lambda x=job: x, outputs=job_input) | |
| with gr.Row(): | |
| for job in jobs[5:10]: | |
| btn = gr.Button(job, size="sm", variant="secondary") | |
| btn.click(fn=lambda x=job: x, outputs=job_input) | |
| # 1. ์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ์์ฑ ํญ | |
| def create_commonly_asked_tab(): | |
| if not available_features.get('commonly_asked'): | |
| gr.Markdown("โ **์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)") | |
| return | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h2>๐ฏ ์ผ๋ฐ์ ์ธ ๋ฉด์ ์ง๋ฌธ ์์ฑ</h2> | |
| <p>ํ์ฌ์ ์ง๋ฌด์ ๋ง์ถคํ ๋ฉด์ ์ง๋ฌธ์ AI๊ฐ ์์ฑํด๋๋ฆฝ๋๋ค</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์ ๋ ฅ**") | |
| company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช ", placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ") | |
| job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ง์ผํ , ๊ธฐํ ๋ฑ") | |
| with gr.Row(): | |
| experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์ ", interactive=True) | |
| num_questions_input = gr.Dropdown(label="๐ ์์ฑํ ์ง๋ฌธ ์", choices=[1, 2, 3, 4, 5], value=3, interactive=True) | |
| common_questions_list = [ | |
| "์๊ธฐ์๊ฐ๋ฅผ ํด๋ณด์ธ์", "์ง์ ๋๊ธฐ๊ฐ ๋ฌด์์ธ๊ฐ์", "๋ณธ์ธ์ ๊ฐ์ ์ ๋ฌด์์ธ๊ฐ์", | |
| "๊ฐ์ฅ ๋์ ์ ์ธ ๊ฒฝํ์ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ณต ๊ฒฝํ์ ๋งํด์ฃผ์ธ์", "์คํจ ๊ฒฝํ์ ๋งํด์ฃผ์ธ์", | |
| "์ ์ฌ ํ ํฌ๋ถ๋ ๋ฌด์์ธ๊ฐ์", "์ฑ๊ฒฉ์ ์ฅ๋จ์ ์ ๋งํด์ฃผ์ธ์", "์กด๊ฒฝํ๋ ์ธ๋ฌผ์ ๋๊ตฌ์ธ๊ฐ์", | |
| "๋ง์ง๋ง์ผ๋ก ํ๊ณ ์ถ์ ๋ง์?" | |
| ] | |
| selected_questions = gr.CheckboxGroup(label="๐ ์ฐธ๊ณ ํ ์ผ๋ฐ ์ง๋ฌธ (์ ํ)", choices=common_questions_list, value=common_questions_list[:3]) | |
| generate_btn = gr.Button("๐ฏ ๋ฉด์ ์ง๋ฌธ ์์ฑ", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| create_example_buttons(example_companies, example_jobs, company_input, job_input) | |
| gr.Markdown("### ๐ **์์ฑ๋ ๋ฉด์ ์ง๋ฌธ**") | |
| result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ '๋ฉด์ ์ง๋ฌธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.") | |
| def process_question_generation(company, job, experience, selected, num): | |
| try: | |
| content, _ = modules['commonly_asked'].generate_interview_questions(company, job, experience, selected, num) | |
| return content | |
| except Exception as e: | |
| return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}" | |
| generate_btn.click( | |
| fn=process_question_generation, | |
| inputs=[company_input, job_input, experience_input, selected_questions, num_questions_input], | |
| outputs=result_output | |
| ) | |
| # 2. ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ํญ | |
| def create_question_recommendation_tab(): | |
| if not available_features.get('question_rec') or not openai_available: | |
| gr.Markdown("โ **๋ฉด์ ์ง๋ฌธ ์ถ์ฒ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ ๋๋ API ํค ์์)") | |
| return | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h2>๐ก ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ</h2> | |
| <p>์ง๋ฌด, ํ์ฌ๋ช , ๊ฒฝ๋ ฅ ์์ค์ ์ ๋ ฅํ๋ฉด AI๊ฐ ๋ง์ถคํ ์ง๋ฌธ์ ์ถ์ฒํฉ๋๋ค</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### ๐ **์ ๋ณด ์ ๋ ฅ**") | |
| job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ง์ผํ , ๊ธฐํ ๋ฑ") | |
| company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช ", placeholder="์: ํ ์ค, ์ผ์ฑ์ ์, ๋ค์ด๋ฒ ๋ฑ") | |
| experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์ ") | |
| submit_btn = gr.Button("๐ก ๋ฉด์ ์ง๋ฌธ ์ถ์ฒ๋ฐ๊ธฐ", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| create_example_buttons(example_companies, example_jobs, company_input, job_input) | |
| gr.Markdown("### ๐ฌ **์ถ์ฒ ๋ฉด์ ์ง๋ฌธ**") | |
| result_output = gr.Textbox(label="", placeholder="์ถ์ฒ๋ ๋ฉด์ ์ง๋ฌธ์ด ์ฌ๊ธฐ์ ํ์๋ฉ๋๋ค.", lines=5, show_label=False, interactive=False) | |
| def recommend_question(job, company, experience): | |
| try: | |
| if not client: return "โ OpenAI API ํค๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค." | |
| prompt_path = current_dir / "question-recommendation" / "prompt.yaml" | |
| with open(prompt_path, 'r', encoding='utf-8') as f: | |
| prompts = yaml.safe_load(f) | |
| result = modules['question_rec'].generate_question_recommendation(client, prompts, job, company, experience) | |
| parsed = modules['question_rec'].parse_question_recommendation(result) | |
| return parsed.get('recommended_question', "์ง๋ฌธ ์์ฑ์ ์คํจํ์ต๋๋ค.") | |
| except Exception as e: | |
| return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}" | |
| submit_btn.click(fn=recommend_question, inputs=[job_input, company_input, experience_input], outputs=result_output) | |
| # 3. ์ง๋ฌด๊ธฐ์ ์ ์์ฑ ํญ | |
| def create_jd_recommendation_tab(): | |
| if not available_features.get('jd_rec'): | |
| gr.Markdown("โ **์ง๋ฌด๊ธฐ์ ์ ์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)") | |
| return | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h2>๐ AI ์ง๋ฌด๊ธฐ์ ์ ์์ฑ๊ธฐ</h2> | |
| <p>๋ง์ถคํ ์ง๋ฌด๊ธฐ์ ์๋ก ์๋ฒฝํ ์๊ธฐ์๊ฐ์๋ฅผ ์ค๋นํ์ธ์</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์ ๋ ฅ**") | |
| job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๊ฒฝ์๊ธฐํ, ๋ฐฑ์๋ ๊ฐ๋ฐ, ์จ๋ผ์ธ๋ง์ผํ ๋ฑ") | |
| company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช ", placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ") | |
| experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์ ", interactive=True) | |
| generate_btn = gr.Button("๐ ์ง๋ฌด๊ธฐ์ ์ ์์ฑ", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| create_example_buttons(example_companies, example_jobs, company_input, job_input) | |
| gr.Markdown("### ๐ **์์ฑ๋ ์ง๋ฌด๊ธฐ์ ์**") | |
| result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ '์ง๋ฌด๊ธฐ์ ์ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.") | |
| def process_jd_generation(job, company, experience): | |
| try: | |
| content, _ = modules['jd_rec'].generate_jd_recommendation(job, company, experience) | |
| return content | |
| except Exception as e: | |
| return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}" | |
| generate_btn.click(fn=process_jd_generation, inputs=[job_input, company_input, experience_input], outputs=result_output) | |
| # 4. ์ฐ์ ๋ถ๋ฅ ํญ | |
| def create_industry_classification_tab(): | |
| if not available_features.get('industry'): | |
| gr.Markdown("โ **์ฐ์ ๋ถ๋ฅ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)") | |
| return | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h2>๐ท๏ธ AI ์ฐ์ ๋ถ๋ฅ๊ธฐ</h2> | |
| <p>์ง๋ฌด์ ํ์ฌ๋ช ์ ๋ฐํ์ผ๋ก ์ ํํ ์ฐ์ ๋ถ์ผ๋ฅผ ๋ถ๋ฅํฉ๋๋ค</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์ ๋ ฅ**") | |
| job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๊ฒฝ์๊ธฐํ, ๋ฐฑ์๋ ๊ฐ๋ฐ, ์จ๋ผ์ธ๋ง์ผํ ๋ฑ") | |
| company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช ", placeholder="์: ์ผ์ฑ์ ์, ํ ์ค, ์นด์นด์ค ๋ฑ") | |
| classify_btn = gr.Button("๐ท๏ธ ์ฐ์ ๋ถ๋ฅ", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| create_example_buttons(example_companies, example_jobs, company_input, job_input) | |
| gr.Markdown("### ๐ **๋ถ๋ฅ ๊ฒฐ๊ณผ**") | |
| result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ '์ฐ์ ๋ถ๋ฅ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.") | |
| def process_classification(job, company): | |
| try: | |
| content, _ = modules['industry'].classify_industry(job, company) | |
| return content | |
| except Exception as e: | |
| return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}" | |
| classify_btn.click(fn=process_classification, inputs=[job_input, company_input], outputs=result_output) | |
| # 5. ์์์ ์ปจํ ์คํธ ๋ฆฌํฌํธ ํญ | |
| def create_jasoseo_context_tab(): | |
| if not available_features.get('jasoseo'): | |
| gr.Markdown("โ **์์์ ์ปจํ ์คํธ ๋ฆฌํฌํธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)") | |
| return | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h2>๐ ์์์ ์ปจํ ์คํธ ๋ฆฌํฌํธ</h2> | |
| <p>๊ธฐ์ ๊ณผ ์ง๋ฌด์ ๋ํ ์ข ํฉ์ ์ธ ๋ถ์์ผ๋ก ์๋ฒฝํ ์๊ธฐ์๊ฐ์๋ฅผ ์ค๋นํ์ธ์</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### ๐ **๊ธฐ๋ณธ ์ ๋ณด ์ ๋ ฅ**") | |
| job_input = gr.Textbox(label="๐ผ ์ง๋ฌด", placeholder="์: ๋ฐฑ์๋ ๊ฐ๋ฐ, ๊ฒฝ์๊ธฐํ, ๋ง์ผํ ๋ฑ") | |
| company_input = gr.Textbox(label="๐ข ํ์ฌ๋ช ", placeholder="์: ํ ์ค, ์ผ์ฑ์ ์, ์นด์นด์ค ๋ฑ") | |
| experience_input = gr.Dropdown(label="๐ ๊ฒฝ๋ ฅ ์์ค", choices=experience_levels, value="์ ์ ", interactive=True) | |
| generate_btn = gr.Button("๐ ๋ฆฌํฌํธ ์์ฑ", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| create_example_buttons(example_companies, example_jobs, company_input, job_input) | |
| gr.Markdown("### ๐ **์ปจํ ์คํธ ๋ฆฌํฌํธ**") | |
| result_output = gr.Markdown("์ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ '๋ฆฌํฌํธ ์์ฑ' ๋ฒํผ์ ํด๋ฆญํ์ธ์.") | |
| def process_report_generation(job, company, experience): | |
| try: | |
| content, _ = modules['jasoseo'].generate_context_report(job, company, experience) | |
| return content | |
| except Exception as e: | |
| return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}" | |
| generate_btn.click(fn=process_report_generation, inputs=[job_input, company_input, experience_input], outputs=result_output) | |
| # 6. ๊ธฐ์ ๊ท๋ชจ ๋ถ๋ฅ ํญ | |
| def create_company_size_tab(): | |
| if not available_features.get('company_size'): | |
| gr.Markdown("โ **๊ธฐ์ ๊ท๋ชจ ๋ถ๋ฅ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.** (๋ชจ๋ ๋ก๋ ์คํจ)") | |
| return | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h2>๐ข AI ๊ธฐ์ ๊ท๋ชจ ์์ธก๊ธฐ</h2> | |
| <p>์ค์๊ฐ ์น ์ ๋ณด๋ฅผ ํ์ฉํ ๊ธฐ์ ์ ๋ณด ๋ถ์</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| gr.Markdown("### ๐ **๊ธฐ์ ์ ๋ณด ์ ๋ ฅ**") | |
| company_input = gr.Textbox(label="๐ข ๊ธฐ์ ๋ช ์ ๋ ฅ", placeholder="๋ถ์ํ๊ณ ์ถ์ ๊ธฐ์ ๋ช ์ ์ ๋ ฅํ์ธ์ (์: ์ผ์ฑ์ ์, ์นด์นด์ค ๋ฑ)") | |
| analyze_btn = gr.Button("๐ ๊ธฐ์ ๊ท๋ชจ ๋ถ์", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| gr.Markdown(""" | |
| ### โน๏ธ **๋ถ๋ฅ ๊ธฐ์ค** | |
| - **๋๊ธฐ์ **: ๋งค์ถ 1์กฐ์ ์ด์ | |
| - **์ค๊ฒฌ๊ธฐ์ **: ๋งค์ถ 1000์ต-1์กฐ์ | |
| - **์ค์๊ธฐ์ **: ๋งค์ถ 1000์ต์ ๋ฏธ๋ง | |
| - **์คํํธ์ **: ์ค๋ฆฝ 10๋ ์ด๋ด | |
| - **์ธ๊ตญ๊ณ๊ธฐ์ **: ํด์ธ ๋ณธ์ฌ | |
| - **๊ณต๊ณต๊ธฐ๊ด/๊ณต๊ธฐ์ **: ์ ๋ถ ์ถ์/์ถ์ฐ | |
| """) | |
| gr.Markdown("### ๐ผ **์์ ๊ธฐ์ ์ ํ** (ํด๋ฆญํ๋ฉด ์๋ ์ ๋ ฅ๋ฉ๋๋ค)") | |
| example_company_names = ["์ผ์ฑ์ ์", "ํ๋์๋์ฐจ", "SKํ์ด๋์ค", "ํฌ์ค์ฝํ๋ฉ์ค", "ํ ์ค", "์นด์นด์ค", "๋ค์ด๋ฒ", "์ฟ ํก", "๋ฐฐ๋ฌ์๋ฏผ์กฑ", "๋น๊ทผ๋ง์ผ"] | |
| with gr.Row(): | |
| for company in example_company_names[:5]: | |
| btn = gr.Button(company, size="sm", variant="secondary") | |
| btn.click(fn=lambda x=company: x, outputs=company_input) | |
| with gr.Row(): | |
| for company in example_company_names[5:]: | |
| btn = gr.Button(company, size="sm", variant="secondary") | |
| btn.click(fn=lambda x=company: x, outputs=company_input) | |
| gr.Markdown("### ๐ **๋ถ์ ๊ฒฐ๊ณผ**") | |
| result_output = gr.Markdown("๊ธฐ์ ๋ช ์ ์ ๋ ฅํ๊ณ '๊ธฐ์ ๊ท๋ชจ ๋ถ์' ๋ฒํผ์ ํด๋ฆญํ์ธ์.") | |
| def process_analysis_result(company): | |
| try: | |
| content, _ = modules['company_size'].analyze_company_size(company) | |
| return content | |
| except Exception as e: | |
| return f"โ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}" | |
| analyze_btn.click(fn=process_analysis_result, inputs=[company_input], outputs=result_output) | |
| # ๋ฉ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์์ฑ | |
| def create_main_app(): | |
| with gr.Blocks( | |
| title="๐ JasoSeo Agent - ์ทจ์ ์ง์ AI ๋๊ตฌ", | |
| theme=gr.themes.Soft(primary_hue="purple", secondary_hue="pink", neutral_hue="gray"), | |
| css=common_css | |
| ) as app: | |
| gr.HTML(""" | |
| <div style="text-align: center; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 15px; margin-bottom: 30px;"> | |
| <h1 style="font-size: 32px; margin-bottom: 10px;">๐ JasoSeo Agent</h1> | |
| <p style="font-size: 18px; margin-bottom: 0; opacity: 0.9;">AI ๊ธฐ๋ฐ ์ทจ์ ์ง์ ํตํฉ ํ๋ซํผ</p> | |
| </div> | |
| """) | |
| status_items = [name for name, ok in available_features.items() if ok] | |
| status_text = f"โ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ ({len(status_items)}/{len(available_features)}): {', '.join(status_items)}" if status_items else "โ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค." | |
| gr.Markdown(f"**{status_text}**") | |
| with gr.Tabs(elem_classes="tab-container"): | |
| with gr.Tab("๐ฏ ๋ฉด์ ์ง๋ฌธ ์์ฑ", elem_id="commonly-asked-tab"): | |
| create_commonly_asked_tab() | |
| with gr.Tab("๐ก ์ง๋ฌธ ์ถ์ฒ", elem_id="question-recommendation-tab"): | |
| create_question_recommendation_tab() | |
| with gr.Tab("๐ ์ง๋ฌด๊ธฐ์ ์", elem_id="jd-recommendation-tab"): | |
| create_jd_recommendation_tab() | |
| with gr.Tab("๐ท๏ธ ์ฐ์ ๋ถ๋ฅ", elem_id="industry-classification-tab"): | |
| create_industry_classification_tab() | |
| with gr.Tab("๐ ์ปจํ ์คํธ ๋ฆฌํฌํธ", elem_id="jasoseo-context-tab"): | |
| create_jasoseo_context_tab() | |
| with gr.Tab("๐ข ๊ธฐ์ ๊ท๋ชจ", elem_id="company-size-tab"): | |
| create_company_size_tab() | |
| return app | |
| if __name__ == "__main__": | |
| if not os.getenv("OPENAI_API_KEY"): | |
| print("โ ๏ธ OPENAI_API_KEY ํ๊ฒฝ ๋ณ์๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค. ์ผ๋ถ ๊ธฐ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.") | |
| print("\n๐ ๋ชจ๋ ๋ก๋ ์ํ:") | |
| for feature, available in available_features.items(): | |
| print(f" {'โ ' if available else 'โ'} {feature}") | |
| print("\n๐ JasoSeo Agent ์์ ์ค...") | |
| app = create_main_app() | |
| app.launch(share=True, show_error=True, debug=True) |