Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import logging | |
| import requests | |
| import json | |
| from typing import Optional | |
| # 配置日志 | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| def generate_email_with_vveai( | |
| profile1: str, | |
| profile2: str, | |
| style: str = "friendly", | |
| temperature: float = 0.7, | |
| api_key: Optional[str] = None | |
| ) -> str: | |
| """ | |
| 使用VVEAI API基于两个LinkedIn简介生成个性化咖啡聊天邀请邮件。 | |
| 参数: | |
| profile1 (str): 发件人的LinkedIn简介文本 | |
| profile2 (str): 收件人的LinkedIn简介文本 | |
| style (str): 邮件风格,可选项为 "formal", "friendly", "humorous" | |
| temperature (float): 生成文本的创造性程度 (0.0-1.0) | |
| api_key (str, optional): VVEAI API密钥 | |
| 返回: | |
| str: 生成的个性化咖啡聊天邮件 | |
| """ | |
| try: | |
| # 验证输入 | |
| if not profile1 or not profile2: | |
| raise ValueError("两个简介都不能为空") | |
| valid_styles = ["formal", "friendly", "humorous"] | |
| if style not in valid_styles: | |
| logging.warning(f"不支持的风格 '{style}',使用默认的 'friendly'") | |
| style = "friendly" | |
| if temperature < 0.0 or temperature > 1.0: | |
| logging.warning(f"温度 {temperature} 超出范围,调整至 0.7") | |
| temperature = 0.7 | |
| # 验证API密钥 | |
| if not api_key: | |
| raise ValueError("请提供VVEAI API密钥") | |
| # 构建提示词 | |
| prompt = f""" | |
| I need to write a personalized coffee chat invitation email based on two LinkedIn profiles. | |
| MY PROFILE: | |
| {profile1} | |
| TARGET PERSON'S PROFILE: | |
| {profile2} | |
| TASK: | |
| 1. Analyze both profiles to identify meaningful common points or connections (universities, companies, industries, skills, interests, etc.) | |
| 2. Write a personalized coffee chat invitation email from me to the target person | |
| 3. The email should: | |
| - Start with a brief introduction of myself | |
| - Mention 2-3 specific commonalities or interesting points from our profiles | |
| - Express genuine interest in their work/experience | |
| - Include a clear but polite request for a 15-30 minute coffee chat | |
| - Suggest flexibility for their schedule | |
| - End with a professional closing | |
| STYLE: | |
| The tone should be {style}. If formal: professional and respectful; if friendly: warm and conversational; if humorous: light and engaging but still professional. | |
| IMPORTANT GUIDELINES: | |
| - Keep the email concise (150-250 words) | |
| - Make it feel authentic and human, not templated | |
| - Focus on creating a genuine connection | |
| - Avoid generic flattery | |
| - Be specific about shared connections or interests | |
| - Don't be pushy or demanding | |
| Format the response as a complete, ready-to-send email without explanations. | |
| """ | |
| # 准备API请求 | |
| system_message = "You are an expert email writer who helps professionals create personalized networking messages." | |
| # VVEAI API端点 | |
| url = "https://api.vveai.com/v1/chat/completions" | |
| # 构建请求 | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {api_key}" | |
| } | |
| payload = { | |
| "model": "gpt-4", # 可能需要根据VVEAI支持的模型调整 | |
| "messages": [ | |
| {"role": "system", "content": system_message}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| "temperature": temperature, | |
| "max_tokens": 1000 | |
| } | |
| # 发送请求 | |
| response = requests.post(url, headers=headers, data=json.dumps(payload), timeout=60) | |
| # 添加详细日志便于调试 | |
| logging.info(f"API响应状态码: {response.status_code}") | |
| logging.info(f"API响应头: {response.headers}") | |
| # 处理响应 | |
| if response.status_code == 200: | |
| result = response.json() | |
| # 记录完整响应便于调试 | |
| logging.info(f"API响应内容: {result}") | |
| try: | |
| email_text = result["choices"][0]["message"]["content"].strip() | |
| return email_text | |
| except KeyError as e: | |
| logging.error(f"响应格式错误: {e}. 完整响应: {result}") | |
| return f"API响应格式错误: {e}。请联系VVEAI支持获取帮助。" | |
| else: | |
| error_message = f"API请求失败: {response.status_code} - {response.text}" | |
| logging.error(error_message) | |
| return f"API错误: {response.status_code}。请检查您的API密钥是否正确。详细信息: {response.text}" | |
| except ValueError as e: | |
| logging.error(f"输入错误: {str(e)}") | |
| return f"发生错误: {str(e)}" | |
| except requests.RequestException as e: | |
| logging.error(f"请求错误: {str(e)}") | |
| return f"网络请求错误: {str(e)}" | |
| except Exception as e: | |
| logging.error(f"意外错误: {str(e)}") | |
| return f"发生未预期的错误: {str(e)}" | |
| # 页面配置 | |
| st.set_page_config( | |
| page_title="个性化咖啡聊天邮件生成器", | |
| page_icon="☕", | |
| layout="wide" | |
| ) | |
| # 标题和说明 | |
| st.title("☕ 个性化咖啡聊天邮件生成器") | |
| st.markdown(""" | |
| 此应用可以帮助求职者生成个性化的咖啡聊天邀请邮件。 | |
| 只需输入您的简介和目标联系人的简介,系统将分析共同点并生成一封真诚的邀请邮件。 | |
| **注意:此应用使用 VVEAI API 服务,请确保输入正确的 API 密钥。** | |
| """) | |
| # 侧边栏 - API设置 | |
| with st.sidebar: | |
| st.header("API设置") | |
| api_key = st.text_input("VVEAI API密钥", type="password", key="api_key", | |
| help="输入以 sk- 开头的 VVEAI API 密钥") | |
| # 添加API状态检测按钮 | |
| if st.button("测试API连接"): | |
| if not api_key: | |
| st.error("请先输入API密钥") | |
| else: | |
| try: | |
| # 简单的API测试请求 | |
| test_url = "https://api.vveai.com/v1/chat/completions" | |
| test_headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {api_key}" | |
| } | |
| test_payload = { | |
| "model": "gpt-4", | |
| "messages": [ | |
| {"role": "user", "content": "Hello"} | |
| ], | |
| "max_tokens": 5 | |
| } | |
| test_response = requests.post( | |
| test_url, | |
| headers=test_headers, | |
| data=json.dumps(test_payload), | |
| timeout=10 | |
| ) | |
| if test_response.status_code == 200: | |
| st.success("API连接成功!") | |
| else: | |
| st.error(f"API连接失败: {test_response.status_code} - {test_response.text}") | |
| except Exception as e: | |
| st.error(f"测试API时出错: {str(e)}") | |
| st.subheader("邮件风格") | |
| style = st.radio( | |
| "选择风格:", | |
| ["formal", "friendly", "humorous"], | |
| index=1, | |
| format_func=lambda x: { | |
| "formal": "正式专业", | |
| "friendly": "友好温暖", | |
| "humorous": "幽默轻松" | |
| }[x] | |
| ) | |
| temperature = st.slider("创造性程度", min_value=0.0, max_value=1.0, value=0.7, step=0.1, | |
| help="较低的值使输出更可预测,较高的值使输出更创意") | |
| # 主界面 - 两栏布局 | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.header("您的简介") | |
| profile1 = st.text_area( | |
| "粘贴您的LinkedIn简介或专业背景", | |
| height=300, | |
| placeholder="例如:\n我是一名拥有5年经验的金融分析师,毕业于北京大学金融学专业。我在摩根士丹利工作了3年,专注于投资银行业务..." | |
| ) | |
| with col2: | |
| st.header("目标联系人的简介") | |
| profile2 = st.text_area( | |
| "粘贴目标联系人的LinkedIn简介或专业背景", | |
| height=300, | |
| placeholder="例如:\n高级投资银行家,现任高盛副总裁。清华大学MBA毕业,擅长并购交易,在科技行业有丰富经验..." | |
| ) | |
| # 生成按钮和结果显示 | |
| submit_disabled = not api_key or not profile1 or not profile2 | |
| if submit_disabled: | |
| if not api_key: | |
| reason = "请先输入VVEAI API密钥" | |
| else: | |
| reason = "请填写两个简介" | |
| st.warning(reason) | |
| if st.button("生成邮件", type="primary", disabled=submit_disabled): | |
| with st.spinner("正在分析简介并创建个性化邮件..."): | |
| email = generate_email_with_vveai( | |
| profile1=profile1, | |
| profile2=profile2, | |
| style=style, | |
| temperature=temperature, | |
| api_key=api_key | |
| ) | |
| # 检查是否发生错误 | |
| if email.startswith("发生错误") or email.startswith("API错误") or email.startswith("网络请求错误"): | |
| st.error(email) | |
| else: | |
| st.success("邮件已生成!") | |
| # 显示结果 | |
| st.header("您的个性化咖啡聊天邮件") | |
| st.text_area("可复制的邮件内容", email, height=400) | |
| st.download_button( | |
| label="下载邮件", | |
| data=email, | |
| file_name="咖啡聊天邀请.txt", | |
| mime="text/plain" | |
| ) | |
| # 调试信息(可选,帮助解决API问题) | |
| if st.checkbox("显示调试信息"): | |
| st.subheader("API信息") | |
| st.markdown(""" | |
| - API端点: `https://api.vveai.com/v1/chat/completions` | |
| - 请求方法: POST | |
| - 内容类型: application/json | |
| - 授权方式: Bearer Token | |
| 如果遇到持续的API问题,请联系VVEAI支持团队并提供以上信息。 | |
| """) | |
| # 使用提示 | |
| st.markdown("---") | |
| st.subheader("💡 使用提示") | |
| st.markdown(""" | |
| - **简介内容越详细**,生成的邮件就越个性化和有针对性 | |
| - **尝试不同风格**以适应不同的行业和联系人 | |
| - 生成后可以**微调邮件内容**,添加您认为合适的个人细节 | |
| - 适合用于**金融、咨询和科技行业**的专业人士 | |
| - 如果API连接测试失败,请确认您的**VVEAI API密钥**是否正确 | |
| """) |