File size: 10,595 Bytes
a9f0320
 
bf9764d
 
a9f0320
 
 
3733579
a9f0320
bf9764d
3733579
 
 
 
 
 
a9f0320
bf9764d
a9f0320
 
3733579
 
a9f0320
3733579
bf9764d
a9f0320
 
3733579
a9f0320
 
3733579
 
 
 
 
 
 
 
 
 
 
 
 
bf9764d
 
 
3733579
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf9764d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3733579
 
bf9764d
 
 
 
 
 
a9f0320
bf9764d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a9f0320
3733579
 
 
bf9764d
 
 
a9f0320
3733579
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf9764d
 
3733579
 
bf9764d
3733579
bf9764d
 
 
 
 
 
 
3733579
bf9764d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3733579
 
 
 
 
 
 
 
 
 
 
a9f0320
 
3733579
 
 
 
 
 
 
 
 
 
 
 
 
a9f0320
3733579
 
 
 
 
 
 
 
 
 
 
 
bf9764d
3733579
 
 
 
 
 
bf9764d
3733579
 
 
 
 
a9f0320
3733579
bf9764d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3733579
bf9764d
 
a9f0320
3733579
 
 
 
 
 
 
 
bf9764d
3733579
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
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密钥**是否正确
""")