Yufan_Zhou commited on
Commit
d8c5622
·
1 Parent(s): fb58205

Fix: Use user preset inputs instead of random generation

Browse files

Core changes:
- User inputs are now directly used (not regenerated)
- Missing fields are generated based on provided inputs
- Added convert_web_profile_to_selector_format() with clear logging
- Fixed data type issues in web_api_bridge.py
- Preserved user_profile.json to avoid overwriting preset values

The system now follows 'use what user provides, generate what's missing' principle.
Console output shows ✓ for user inputs and ✗ for generated fields.

BUGFIX_SUMMARY.md ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bug Fix Summary - Profile Generation Not Using Preset Inputs
2
+
3
+ ## 问题描述
4
+ 当用户通过Web界面输入部分预设内容(如年龄、性别、职业等)时,生成的profile仍然是完全随机的,没有使用用户的预设输入。
5
+
6
+ ## 用户需求
7
+ **核心原则:用户输入了什么就用什么,没输入的才基于已输入内容生成**
8
+ - 用户输入的字段:直接使用,不调用GPT重新生成
9
+ - 用户未输入的字段:基于已输入的字段,调用 `based_data.py` 中的函数生成
10
+ - 有多少用多少,灵活处理部分输入的情况
11
+
12
+ ## 根本原因
13
+ 在 `generate_profile.py` 的 `generate_single_profile()` 函数中,代码会调用 `select_attributes.py` 中的 `generate_user_profile()` 函数来重新生成用户配置文件。这个函数会**完全随机生成**所有基础信息(年龄、性别、职业、地点等),从而覆盖了用户在 `web_api_bridge.py` 中预设的输入。
14
+
15
+ ### 问题代码流程:
16
+ 1. 用户在Web界面输入预设值
17
+ 2. `web_api_bridge.py` 将预设值保存到 `user_profile.json`
18
+ 3. `generate_single_profile()` 被调用
19
+ 4. **问题点**: `generate_single_profile()` 调用 `generate_user_profile()` 重新随机生成配置
20
+ 5. 新生成的随机配置覆盖了用户的预设输入
21
+
22
+ ## 修复方案
23
+
24
+ ### 1. 修改 `generate_profile.py` (主要修改)
25
+ **文件**: `/Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/generate_profile.py`
26
+
27
+ **修改内容**:
28
+ - 在调用属性选择之前,检查是否已存在 `user_profile.json`(由 `web_api_bridge.py` 保存)
29
+ - 如果存在,读取并使用该文件(包含用户预设输入)
30
+ - 将 web 格式的配置转换为 `AttributeSelector` 期望的格式
31
+ - 在属性选择完成后,恢复原始的 `user_profile.json`,避免被覆盖
32
+
33
+ **关键代码**:
34
+ ```python
35
+ # 检查是否已经存在user_profile.json(由web_api_bridge.py保存)
36
+ if os.path.exists(user_profile_path):
37
+ # 读取已存在的用户配置文件(包含预设输入)
38
+ print(f"Found existing user_profile.json, using preset inputs...")
39
+ with open(user_profile_path, 'r', encoding='utf-8') as f:
40
+ base_profile = json.load(f)
41
+
42
+ # 保存原始配置,稍后恢复
43
+ original_base_profile = base_profile.copy()
44
+ using_preset = True
45
+
46
+ # 转换为AttributeSelector期望的格式
47
+ user_profile = convert_web_profile_to_selector_format(base_profile)
48
+ else:
49
+ # 如果不存在,生成新的配置文件
50
+ user_profile = gen_profile()
51
+ ```
52
+
53
+ ### 2. 添加格式转换函数到 `select_attributes.py`
54
+ **文件**: `/Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/select_attributes.py`
55
+
56
+ **新增函数**: `convert_web_profile_to_selector_format()`
57
+
58
+ **功能**: 将 `web_api_bridge.py` 保存的配置格式转换为 `AttributeSelector` 期望的格式
59
+
60
+ **核心逻辑**(严格遵循"有多少用多少"原则):
61
+ ```python
62
+ # 对每个字段进行检查:
63
+ # 1. 如果用户提供了该字段 → 直接使用,打印 "✓ Using user-provided ..."
64
+ # 2. 如果用户没提供 → 基于已有信息生成,打印 "✗ ... not provided, generated ..."
65
+
66
+ # 示例:年龄处理
67
+ age = web_profile.get("age")
68
+ if age:
69
+ age_info = {"age": age, "age_group": calculate_age_group(age)}
70
+ print(f"✓ Using user-provided age: {age}")
71
+ else:
72
+ age_info = generate_age_info() # 只有没提供时才生成
73
+ print(f"✗ Age not provided, generated: {age_info['age']}")
74
+ ```
75
+
76
+ **格式对比**:
77
+ - Web格式: `{"age": int, "gender": str, "Occupations": [str], ...}`
78
+ - Selector格式: `{"age_info": {"age": int, "age_group": str}, "gender": str, "career_info": {"status": str}, ...}`
79
+
80
+ **处理的字段**:
81
+ - ✅ age → age_info (如果提供了就用,否则生成)
82
+ - ✅ gender (如果提供了就用,否则生成)
83
+ - ✅ location (如果提供了就用,否则生成)
84
+ - ✅ Occupations → career_info (如果提供了就用,否则生成)
85
+ - ✅ personal_values (如果提供了就用,否则基于已有信息生成)
86
+ - ✅ life_attitude (如果提供了就用,否则基于已有信息生成)
87
+ - ✅ personal_story (如果提供了就用,否则基于已有信息生成)
88
+ - ✅ interests (如果提供了就用,否则基于故事生成)
89
+
90
+ ### 3. 修复 `web_api_bridge.py` 中的数据类型问题
91
+ **文件**: `/Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/web_api_bridge.py`
92
+
93
+ **修复内容**:
94
+ 1. **修复 `values_orientation` 类型问题**:
95
+ - `generate_personal_values()` 返回字典,需要提取 `values_orientation` 字段
96
+
97
+ 2. **修复 `personal_story` 嵌套问题**:
98
+ - 避免重复嵌套 `{"personal_story": {"personal_story": ...}}`
99
+
100
+ ## 修改文件列表
101
+ 1. ✅ `/Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/generate_profile.py`
102
+ 2. ✅ `/Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/select_attributes.py`
103
+ 3. ✅ `/Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code/web_api_bridge.py`
104
+
105
+ ## 测试建议
106
+
107
+ ### 测试场景 1:部分输入(只输入基本信息)
108
+ **输入**:
109
+ - Age: 25
110
+ - Gender: Male
111
+ - Occupation: Software Engineer
112
+ - City: Tokyo
113
+ - Country: Japan
114
+
115
+ **预期输出**:
116
+ ```
117
+ ✓ Using user-provided age: 25
118
+ ✓ Using user-provided gender: Male
119
+ ✓ Using user-provided location: Tokyo, Japan
120
+ ✓ Using user-provided occupation: Software Engineer
121
+ ✗ Personal values not provided, generated based on user inputs
122
+ ✗ Life attitude not provided, generated based on user inputs
123
+ ✗ Life story not provided, generated based on user inputs
124
+ ✗ Interests not provided, generated based on life story
125
+ ```
126
+
127
+ ### 测试场景 2:完整输入(输入所有字段)
128
+ **输入**:
129
+ - Age: 30
130
+ - Gender: Female
131
+ - Occupation: Teacher
132
+ - Location: Paris, France
133
+ - Personal Values: "Values education and creativity"
134
+ - Life Attitude: "Optimistic and passionate about learning"
135
+ - Life Story: "Born in Lyon, moved to Paris for university..."
136
+ - Interests: "Reading, painting, traveling"
137
+
138
+ **预期输出**:
139
+ ```
140
+ ✓ Using user-provided age: 30
141
+ ✓ Using user-provided gender: Female
142
+ ✓ Using user-provided location: Paris, France
143
+ ✓ Using user-provided occupation: Teacher
144
+ ✓ Using user-provided personal values: Values education and creativity
145
+ ✓ Using user-provided life attitude: Optimistic and passionate about learning
146
+ ✓ Using user-provided life story: Born in Lyon, moved to Paris for university...
147
+ ✓ Using user-provided interests: Reading, painting, traveling
148
+ ```
149
+
150
+ ### 测试场景 3:空输入(完全随机生成)
151
+ **输入**: 全部留空
152
+
153
+ **预期输出**:
154
+ ```
155
+ ✗ Age not provided, generated: 42
156
+ ✗ Gender not provided, generated: female
157
+ ✗ Location not provided, generated: Mumbai, India
158
+ ✗ Occupation not provided, generated: Marketing Manager
159
+ ✗ Personal values not provided, generated based on user inputs
160
+ ✗ Life attitude not provided, generated based on user inputs
161
+ ✗ Life story not provided, generated based on user inputs
162
+ ✗ Interests not provided, generated based on life story
163
+ ```
164
+
165
+ ## 预期结果
166
+ - ✅ 用户输入的预设值会被**直接使用**,不会被重新生成
167
+ - ✅ 未输入的字段会基于已输入的信息**智能生成**
168
+ - ✅ 生成的profile与用户输入保持**完全一致性**
169
+ - ✅ 控制台会清晰显示哪些字段使用了用户输入(✓),哪些是生成的(✗)
TEST_EXAMPLE.md ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 测试示例 - 验证用户输入是否被正确使用
2
+
3
+ ## 如何测试
4
+
5
+ ### 方法 1: 通过 Web 界面测试
6
+
7
+ 1. 启动应用:
8
+ ```bash
9
+ cd /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience
10
+ python app.py
11
+ ```
12
+
13
+ 2. 在浏览器中打开 `http://localhost:7860`
14
+
15
+ 3. 输入测试数据(例如):
16
+ - **Age**: 28
17
+ - **Gender**: Male
18
+ - **Occupation**: Data Scientist
19
+ - **City**: San Francisco
20
+ - **Country**: USA
21
+ - **Personal Values**: (留空,测试自动生成)
22
+ - **Life Attitude**: "Curious and analytical"
23
+ - **Life Story**: (留空,测试自动生成)
24
+ - **Interests and Hobbies**: "Machine learning, hiking"
25
+
26
+ 4. 点击 "Generate Character Profile"
27
+
28
+ 5. **检查控制台输出**,应该看到类似:
29
+ ```
30
+ Found existing user_profile.json, using preset inputs...
31
+ ✓ Using user-provided age: 28
32
+ ✓ Using user-provided gender: Male
33
+ ✓ Using user-provided location: San Francisco, USA
34
+ ✓ Using user-provided occupation: Data Scientist
35
+ ✗ Personal values not provided, generated based on user inputs
36
+ ✓ Using user-provided life attitude: Curious and analytical
37
+ ✗ Life story not provided, generated based on user inputs
38
+ ✓ Using user-provided interests: Machine learning, hiking
39
+ ```
40
+
41
+ 6. **检查生成的 Profile**,应该包含:
42
+ - 年龄 28 岁
43
+ - 性别 Male
44
+ - 职业 Data Scientist
45
+ - 地点 San Francisco, USA
46
+ - 生活态度包含 "Curious and analytical"
47
+ - 兴趣包含 "Machine learning" 和 "hiking"
48
+
49
+ ### 方法 2: 通过命令行测试
50
+
51
+ 1. 创建测试输入文件 `test_input.json`:
52
+ ```json
53
+ {
54
+ "basic_info": {
55
+ "age": 25,
56
+ "gender": "Female",
57
+ "occupation": {
58
+ "status": "Software Engineer"
59
+ },
60
+ "location": {
61
+ "city": "Tokyo",
62
+ "country": "Japan"
63
+ }
64
+ },
65
+ "custom_values": {
66
+ "personal_values": "Values innovation and teamwork",
67
+ "life_attitude": "",
68
+ "life_story": "",
69
+ "interests_hobbies": "Coding, anime, gaming"
70
+ }
71
+ }
72
+ ```
73
+
74
+ 2. 运行测试:
75
+ ```bash
76
+ cd /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/code
77
+ python web_api_bridge.py --input test_input.json --attributes 200
78
+ ```
79
+
80
+ 3. **检查输出**,应该显示:
81
+ ```
82
+ ✓ Using user-provided age: 25
83
+ ✓ Using user-provided gender: Female
84
+ ✓ Using user-provided location: Tokyo, Japan
85
+ ✓ Using user-provided occupation: Software Engineer
86
+ ✓ Using user-provided personal values: Values innovation and teamwork
87
+ ✗ Life attitude not provided, generated based on user inputs
88
+ ✗ Life story not provided, generated based on user inputs
89
+ ✓ Using user-provided interests: Coding, anime, gaming
90
+ ```
91
+
92
+ ## 验证要点
93
+
94
+ ### ✅ 正确行为
95
+ 1. 用户输入的字段显示 `✓ Using user-provided ...`
96
+ 2. 未输入的字段显示 `✗ ... not provided, generated ...`
97
+ 3. 生成的 profile 包含所有用户输入的内容
98
+ 4. 未输入的字段基于已输入内容合理生成(不是完全随机)
99
+
100
+ ### ❌ 错误行为(如果看到这些,说明修复失败)
101
+ 1. 所有字段都显示 `✗ ... not provided, generated ...`(说明用户输入被忽略)
102
+ 2. 用户输入的年龄、性别等与生成的 profile 不匹配
103
+ 3. 生成的内容与用户输入完全无关
104
+
105
+ ## 调试提示
106
+
107
+ 如果测试失败,检查以下内容:
108
+
109
+ 1. **检查 `user_profile.json` 是否正确保存**:
110
+ ```bash
111
+ cat /Users/yufan_zhou/Documents/deeppersona/deeppersona-experience/generate_user_profile_final/output/user_profile.json
112
+ ```
113
+
114
+ 2. **检查控制台是否显示 "Found existing user_profile.json"**:
115
+ - 如果没有,说明文件路径不对
116
+ - 如果显示 "No existing user_profile.json found",说明文件没有被保存
117
+
118
+ 3. **检查是否有错误信息**:
119
+ - 查看完整的 traceback
120
+ - 检查是否有 JSON 解析错误
121
+ - 检查是否有字段类型不匹配的错误
generate_user_profile_final/code/generate_profile.py CHANGED
@@ -372,28 +372,71 @@ def generate_single_profile(template: Dict = None, profile_index: int = 0, attri
372
  """
373
 
374
 
375
- # First, run select_attributes.py to update base files (user_profile.json and selected_paths.json)
376
- print(f'Running select_attributes.py to update base files with {attribute_count} attributes...')
 
377
  try:
378
  # 直接导入select_attributes模块的函数,而不是通过subprocess运行
379
  import sys
380
  import os
381
  sys.path.append(os.path.dirname(os.path.abspath(__file__)))
382
- from select_attributes import generate_user_profile as gen_profile
383
- from select_attributes import get_selected_attributes, save_results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
 
385
- # 生成用户配置文件
386
- user_profile = gen_profile()
387
  # 获取指定数量的属性
388
  selected_paths = get_selected_attributes(user_profile, attribute_count)
389
- # 保存结果
390
- correct_output_dir = os.path.join(get_project_root(), "output")
391
- save_results(user_profile, selected_paths, correct_output_dir)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
 
393
  # 复制文件从源位置到目标位置
394
  copy_files_from_source_to_target()
395
  except Exception as e:
396
  print(f"Error executing select_attributes functions: {e}")
 
 
397
  return {}
398
 
399
  # Load basic profile information and selected paths (base info is only a reference for GPT generation)
 
372
  """
373
 
374
 
375
+ # First, check if user_profile.json already exists (from web_api_bridge.py)
376
+ # If it exists, use it; otherwise generate a new one
377
+ print(f'Preparing to select {attribute_count} attributes...')
378
  try:
379
  # 直接导入select_attributes模块的函数,而不是通过subprocess运行
380
  import sys
381
  import os
382
  sys.path.append(os.path.dirname(os.path.abspath(__file__)))
383
+ from select_attributes import get_selected_attributes, save_results, convert_web_profile_to_selector_format
384
+
385
+ # 检查是否已经存在user_profile.json(由web_api_bridge.py保存)
386
+ correct_output_dir = os.path.join(get_project_root(), "output")
387
+ user_profile_path = os.path.join(correct_output_dir, 'user_profile.json')
388
+
389
+ # 标记是否使用了预设配置
390
+ using_preset = False
391
+ original_base_profile = None
392
+
393
+ if os.path.exists(user_profile_path):
394
+ # 读取已存在的用户配置文件(包含预设输入)
395
+ print(f"Found existing user_profile.json, using preset inputs...")
396
+ with open(user_profile_path, 'r', encoding='utf-8') as f:
397
+ base_profile = json.load(f)
398
+
399
+ # 保存原始配置,稍后恢复
400
+ original_base_profile = base_profile.copy()
401
+ using_preset = True
402
+
403
+ # 转换为AttributeSelector期望的格式
404
+ user_profile = convert_web_profile_to_selector_format(base_profile)
405
+ print(f"Using preset profile with age={user_profile.get('age_info', {}).get('age')}, gender={user_profile.get('gender')}")
406
+ else:
407
+ # 如果不存在,生成新的配置文件
408
+ print("No existing user_profile.json found, generating new random profile...")
409
+ from select_attributes import generate_user_profile as gen_profile
410
+ user_profile = gen_profile()
411
 
 
 
412
  # 获取指定数量的属性
413
  selected_paths = get_selected_attributes(user_profile, attribute_count)
414
+
415
+ # 只保存selected_paths,不覆盖user_profile.json
416
+ # 如果使用了预设配置,需要恢复原始文件
417
+ if using_preset and original_base_profile:
418
+ # 恢复原始的user_profile.json(web格式)
419
+ with open(user_profile_path, 'w', encoding='utf-8') as f:
420
+ json.dump(original_base_profile, f, ensure_ascii=False, indent=2)
421
+ print(f"Restored original user_profile.json with preset inputs")
422
+ else:
423
+ # 如果是新生成的,保存完整结果
424
+ save_results(user_profile, selected_paths, correct_output_dir)
425
+
426
+ # 无论哪种情况,都要保存selected_paths
427
+ from select_attributes import build_nested_dict
428
+ nested_selected_paths = build_nested_dict(selected_paths)
429
+ paths_path = os.path.join(correct_output_dir, "selected_paths.json")
430
+ with open(paths_path, 'w', encoding='utf-8') as f:
431
+ json.dump(nested_selected_paths, f, ensure_ascii=False, indent=2)
432
+ print(f"Saved selected_paths.json with {len(selected_paths)} attributes")
433
 
434
  # 复制文件从源位置到目标位置
435
  copy_files_from_source_to_target()
436
  except Exception as e:
437
  print(f"Error executing select_attributes functions: {e}")
438
+ import traceback
439
+ traceback.print_exc()
440
  return {}
441
 
442
  # Load basic profile information and selected paths (base info is only a reference for GPT generation)
generate_user_profile_final/code/select_attributes.py CHANGED
@@ -772,6 +772,199 @@ class AttributeSelector:
772
 
773
 
774
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
775
  def generate_user_profile() -> Dict:
776
  """生成用户基础信息配置文件"""
777
  # 生成并存储直接函数返回值
 
772
 
773
 
774
 
775
+ def convert_web_profile_to_selector_format(web_profile: Dict) -> Dict:
776
+ """
777
+ 将web_api_bridge.py保存的配置文件格式转换为AttributeSelector期望的格式
778
+
779
+ 核心原则:用户输入了什么就用什么,没输入的才生成
780
+
781
+ web_profile格式:
782
+ {
783
+ "age": int,
784
+ "gender": str,
785
+ "Occupations": [str],
786
+ "location": {"city": str, "country": str},
787
+ "personal_values": {"values_orientation": str},
788
+ "life_attitude": str or dict,
789
+ "personal_story": {"personal_story": str},
790
+ "interests": {"interests": [str]}
791
+ }
792
+
793
+ selector格式:
794
+ {
795
+ "age_info": {"age": int, "age_group": str},
796
+ "gender": str,
797
+ "location": {"city": str, "country": str},
798
+ "career_info": {"status": str},
799
+ "personal_values": {"values_orientation": str},
800
+ "life_attitude": {"attitude": str, "attitude_details": str, "coping_mechanism": str},
801
+ "personal_story": {"personal_story": str},
802
+ "interests": {"interests": [str]}
803
+ }
804
+ """
805
+ # 提取年龄信息 - 如果用户提供了就用,否则生成
806
+ age = web_profile.get("age")
807
+ if age:
808
+ # 根据年龄确定年龄组
809
+ if age <= 6:
810
+ age_group = "toddler"
811
+ elif age <= 12:
812
+ age_group = "child"
813
+ elif age <= 19:
814
+ age_group = "adolescent"
815
+ elif age <= 29:
816
+ age_group = "young_adult"
817
+ elif age <= 45:
818
+ age_group = "adult"
819
+ elif age <= 65:
820
+ age_group = "middle_aged"
821
+ else:
822
+ age_group = "senior"
823
+
824
+ age_info = {"age": age, "age_group": age_group}
825
+ print(f"✓ Using user-provided age: {age}")
826
+ else:
827
+ age_info = generate_age_info()
828
+ print(f"✗ Age not provided, generated: {age_info['age']}")
829
+
830
+ # 提取性别 - 如果用户提供了就用,否则生成
831
+ gender = web_profile.get("gender")
832
+ if gender:
833
+ print(f"✓ Using user-provided gender: {gender}")
834
+ else:
835
+ gender = generate_gender()
836
+ print(f"✗ Gender not provided, generated: {gender}")
837
+
838
+ # 提取位置 - 如果用户提供了就用,否则生成
839
+ location = web_profile.get("location")
840
+ if location and location.get("city") and location.get("country"):
841
+ print(f"✓ Using user-provided location: {location.get('city')}, {location.get('country')}")
842
+ else:
843
+ location = generate_location()
844
+ print(f"✗ Location not provided, generated: {location.get('city')}, {location.get('country')}")
845
+
846
+ # 提取职业信息 - 如果用户提供了就用,否则生成
847
+ occupations = web_profile.get("Occupations", [])
848
+ if occupations and len(occupations) > 0 and occupations[0]:
849
+ career_info = {"status": occupations[0]}
850
+ print(f"✓ Using user-provided occupation: {occupations[0]}")
851
+ else:
852
+ career_info = generate_career_info(age_info["age"])
853
+ print(f"✗ Occupation not provided, generated: {career_info['status']}")
854
+
855
+ # 提取个人价值观 - 如果用户提供了就用,否则生成
856
+ personal_values = web_profile.get("personal_values", {})
857
+ values_orientation = personal_values.get("values_orientation", "")
858
+ if values_orientation and values_orientation.strip():
859
+ # 用户提供了价值观,直接使用
860
+ personal_values = {"values_orientation": values_orientation.strip()}
861
+ print(f"✓ Using user-provided personal values: {values_orientation[:50]}...")
862
+ else:
863
+ # 用户没提供,基于已有信息生成
864
+ personal_values = generate_personal_values(
865
+ age=age_info["age"],
866
+ gender=gender,
867
+ occupation=career_info["status"],
868
+ location=location
869
+ )
870
+ print(f"✗ Personal values not provided, generated based on user inputs")
871
+
872
+ # 提取生活态度 - 如果用户提供了就用,否则生成
873
+ life_attitude_data = web_profile.get("life_attitude")
874
+ if life_attitude_data:
875
+ if isinstance(life_attitude_data, str) and life_attitude_data.strip():
876
+ # 用户提供了字符串格式的生活态度
877
+ life_attitude = {
878
+ "attitude": life_attitude_data.strip(),
879
+ "attitude_details": "",
880
+ "coping_mechanism": ""
881
+ }
882
+ print(f"✓ Using user-provided life attitude: {life_attitude_data[:50]}...")
883
+ elif isinstance(life_attitude_data, dict) and life_attitude_data.get("attitude"):
884
+ # 用户提供了字典格式的生活态度
885
+ life_attitude = life_attitude_data
886
+ print(f"✓ Using user-provided life attitude (dict format)")
887
+ else:
888
+ # 数据格式不对或为空,生成新的
889
+ life_attitude = generate_life_attitude(
890
+ age=age_info["age"],
891
+ gender=gender,
892
+ occupation=career_info["status"],
893
+ location=location,
894
+ values_orientation=personal_values.get("values_orientation", "")
895
+ )
896
+ print(f"✗ Life attitude not provided, generated based on user inputs")
897
+ else:
898
+ # 用户没提供,基于已有信息生成
899
+ life_attitude = generate_life_attitude(
900
+ age=age_info["age"],
901
+ gender=gender,
902
+ occupation=career_info["status"],
903
+ location=location,
904
+ values_orientation=personal_values.get("values_orientation", "")
905
+ )
906
+ print(f"✗ Life attitude not provided, generated based on user inputs")
907
+
908
+ # 提取个人故事 - 如果用户提供了就用,否则生成
909
+ personal_story_data = web_profile.get("personal_story", {})
910
+ if isinstance(personal_story_data, dict) and personal_story_data.get("personal_story"):
911
+ story_text = personal_story_data.get("personal_story", "")
912
+ if story_text and story_text.strip():
913
+ # 用户提供了故事,直接使用
914
+ personal_story = {"personal_story": story_text.strip()}
915
+ print(f"✓ Using user-provided life story: {story_text[:50]}...")
916
+ else:
917
+ # 故事为空,生成新的
918
+ personal_story = generate_personal_story(
919
+ age=age_info["age"],
920
+ gender=gender,
921
+ occupation=career_info["status"],
922
+ location=location,
923
+ values_orientation=personal_values.get("values_orientation", ""),
924
+ life_attitude=life_attitude
925
+ )
926
+ print(f"✗ Life story not provided, generated based on user inputs")
927
+ elif isinstance(personal_story_data, str) and personal_story_data.strip():
928
+ # 用户提供了字符串格式的故事
929
+ personal_story = {"personal_story": personal_story_data.strip()}
930
+ print(f"✓ Using user-provided life story (string format)")
931
+ else:
932
+ # 用户没提供,基于已有信息生成
933
+ personal_story = generate_personal_story(
934
+ age=age_info["age"],
935
+ gender=gender,
936
+ occupation=career_info["status"],
937
+ location=location,
938
+ values_orientation=personal_values.get("values_orientation", ""),
939
+ life_attitude=life_attitude
940
+ )
941
+ print(f"✗ Life story not provided, generated based on user inputs")
942
+
943
+ # 提取兴趣爱好 - 如果用户提供了就用,否则生成
944
+ interests = web_profile.get("interests", {})
945
+ interests_list = interests.get("interests", [])
946
+ if interests_list and len(interests_list) > 0 and any(i.strip() for i in interests_list):
947
+ # 用户提供了兴趣爱好,直接使用
948
+ interests = {"interests": [i.strip() for i in interests_list if i.strip()]}
949
+ print(f"✓ Using user-provided interests: {', '.join(interests['interests'])}")
950
+ else:
951
+ # 用户没提供,基于故事生成
952
+ interests = generate_interests_and_hobbies(personal_story)
953
+ print(f"✗ Interests not provided, generated based on life story")
954
+
955
+ # 返回转换后的格式
956
+ return {
957
+ "age_info": age_info,
958
+ "gender": gender,
959
+ "location": location,
960
+ "career_info": career_info,
961
+ "personal_values": personal_values,
962
+ "life_attitude": life_attitude,
963
+ "personal_story": personal_story,
964
+ "interests": interests
965
+ }
966
+
967
+
968
  def generate_user_profile() -> Dict:
969
  """生成用户基础信息配置文件"""
970
  # 生成并存储直接函数返回值
generate_user_profile_final/code/web_api_bridge.py CHANGED
@@ -103,7 +103,8 @@ def generate_profile_from_input(input_data: Dict[str, Any], attribute_count: int
103
  values_orientation = custom_personal_values.strip()
104
  else:
105
  print("Generating personal values...")
106
- values_orientation = generate_personal_values(age, gender, occupation, location_info)
 
107
 
108
  # Use custom life attitude if provided, otherwise generate it
109
  custom_life_attitude = custom_values.get('life_attitude')
@@ -148,9 +149,7 @@ def generate_profile_from_input(input_data: Dict[str, Any], attribute_count: int
148
  "values_orientation": values_orientation
149
  },
150
  "life_attitude": life_attitude.get("outlook") if isinstance(life_attitude, dict) else str(life_attitude),
151
- "personal_story": {
152
- "personal_story": personal_story
153
- },
154
  "interests": interests_and_hobbies
155
  }
156
 
 
103
  values_orientation = custom_personal_values.strip()
104
  else:
105
  print("Generating personal values...")
106
+ values_dict = generate_personal_values(age, gender, occupation, location_info)
107
+ values_orientation = values_dict.get("values_orientation", "") if isinstance(values_dict, dict) else str(values_dict)
108
 
109
  # Use custom life attitude if provided, otherwise generate it
110
  custom_life_attitude = custom_values.get('life_attitude')
 
149
  "values_orientation": values_orientation
150
  },
151
  "life_attitude": life_attitude.get("outlook") if isinstance(life_attitude, dict) else str(life_attitude),
152
+ "personal_story": personal_story if isinstance(personal_story, dict) else {"personal_story": personal_story},
 
 
153
  "interests": interests_and_hobbies
154
  }
155