import os import configparser from docx import Document import gradio as gr from langchain_openai import AzureChatOpenAI print(gr.__version__) # 讀取 config.ini 文件 def load_config(config_file_path): config = configparser.ConfigParser() try: config.read(config_file_path) if not config.sections(): raise ValueError("config.ini 檔案缺少區段標題,請確認檔案格式正確。") except Exception as e: raise ValueError(f"讀取 config.ini 檔案時發生錯誤:{e}") return config # 設定 Azure OpenAI 配置 def create_openai_client(config): try: return AzureChatOpenAI( openai_api_version=config["AzureOpenAI"]["VERSION"], azure_deployment=config["AzureOpenAI"]["DEPLOYMENT_NAME_GPT4o"], azure_endpoint=config["AzureOpenAI"]["BASE"], api_key=config["AzureOpenAI"]["KEY"], temperature=0.2, ) except KeyError as e: raise ValueError(f"config.ini 檔案缺少必要的欄位:{e}") def read_docx(file): """Reads the content of a .docx file and returns the text.""" doc = Document(file) return "\n".join([para.text for para in doc.paragraphs]) def generate_monthly_report(weekly_reports_files, last_month_report_file, llm_gpt4o): """根據本月份週報與上個月月報產生本月月報。""" weekly_reports = [read_docx(file) for file in weekly_reports_files] last_month_report = read_docx(last_month_report_file) if last_month_report_file else "" # 構建 prompt prompt = f""" 上個月月報內容如下: {last_month_report} --- 本月份週報內容如下: """ for i, report in enumerate(weekly_reports, 1): prompt += f"【第 {i} 週週報】\n{report}\n---\n" prompt += """ 請依據上方提供的「上個月月報」與「本月份週報」進行以下任務: 1. 依照週報的時間順序,整理各專案在本月份的整體進度與內容(像故事一樣描述本月發生的事情)。 2. 依照「上個月月報」的格式,針對每個專案整理本月份已完成的工作內容。 3. 針對每個專案寫出下個月的預計工作計畫,格式與內容參考「上個月月報」的「下月預計工作」。 4. 在報告最後,再統整列出一次每個專案下個月的工作項目(像行動項目)。 ⚠️請用**繁體中文**撰寫,語氣正式、專業。 ⚠️請完全依照「上個月月報」的段落、標題、格式風格來呈現,包含每個專案的順序與排版方式。 資料來源:上方的「上個月月報」與「本月份週報」。 """ try: response = llm_gpt4o.invoke([ ("system", "你是一位專業的助理,負責撰寫正式的工作月報。"), ("human", prompt) ]) return response.content except Exception as e: raise ValueError(f"生成月報時發生錯誤:{str(e)}") def process_reports(weekly_reports_files, last_month_report_file, config_file): try: config_file_path = config_file.name config = load_config(config_file_path) llm_gpt4o = create_openai_client(config) if not weekly_reports_files or not last_month_report_file: return "請上傳所有必需的檔案(週報和上個月月報)。" return generate_monthly_report(weekly_reports_files, last_month_report_file, llm_gpt4o) except Exception as e: return f"生成月報時發生錯誤:{str(e)}" # Gradio Blocks interface with gr.Blocks() as demo: gr.Markdown("# 月報生成工具") gr.Markdown("上傳週報和上個月的月報,並生成本月的月報。") with gr.Row(): weekly_reports_input = gr.File(label="上傳本月週報(多個 .docx 檔案)", file_types=[".docx"], file_count="multiple") last_month_report_input = gr.File(label="上傳上個月月報(單個 .docx 檔案)", file_types=[".docx"]) config_file_input = gr.File(label="上傳 config.ini 檔案") output = gr.Textbox(label="生成的月報") submit_button = gr.Button("生成月報") submit_button.click(process_reports, inputs=[weekly_reports_input, last_month_report_input, config_file_input], outputs=output) demo.launch()