@lobehub/lobehub 2.1.23 → 2.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.github/workflows/claude-auto-e2e-testing.yml +131 -0
  2. package/CHANGELOG.md +42 -0
  3. package/changelog/v2.json +14 -0
  4. package/docs/development/database-schema.dbml +43 -14
  5. package/package.json +1 -1
  6. package/packages/database/migrations/0078_added_id_nanoid_for_replacing_id.sql +7 -0
  7. package/packages/database/migrations/0079_update_id_nanoid_from_casted_id.sql +7 -0
  8. package/packages/database/migrations/0080_add_constraint_unique_not_null_to_id_nanoid.sql +27 -0
  9. package/packages/database/migrations/0081_switch_forgien_key_to_id_nanoid.sql +37 -0
  10. package/packages/database/migrations/0082_set_id_nanoid_as_primary.sql +20 -0
  11. package/packages/database/migrations/0083_remove_id_seq_identity_column.sql +7 -0
  12. package/packages/database/migrations/0084_rename_id_nanoid_to_id.sql +53 -0
  13. package/packages/database/migrations/0085_remove_id_unique_constraint.sql +7 -0
  14. package/packages/database/migrations/meta/0078_snapshot.json +11515 -0
  15. package/packages/database/migrations/meta/0079_snapshot.json +11515 -0
  16. package/packages/database/migrations/meta/0080_snapshot.json +11554 -0
  17. package/packages/database/migrations/meta/0081_snapshot.json +11554 -0
  18. package/packages/database/migrations/meta/0082_snapshot.json +11554 -0
  19. package/packages/database/migrations/meta/0083_snapshot.json +11435 -0
  20. package/packages/database/migrations/meta/0084_snapshot.json +11435 -0
  21. package/packages/database/migrations/meta/0085_snapshot.json +11396 -0
  22. package/packages/database/migrations/meta/_journal.json +56 -0
  23. package/packages/database/src/models/__tests__/apiKey.test.ts +18 -6
  24. package/packages/database/src/models/apiKey.ts +5 -5
  25. package/packages/database/src/schemas/apiKey.ts +6 -2
  26. package/packages/database/src/schemas/ragEvals.ts +27 -20
  27. package/packages/database/src/schemas/rbac.ts +15 -15
  28. package/packages/database/src/server/models/ragEval/dataset.ts +3 -3
  29. package/packages/database/src/server/models/ragEval/datasetRecord.ts +5 -5
  30. package/packages/database/src/server/models/ragEval/evaluation.ts +3 -3
  31. package/packages/database/src/server/models/ragEval/evaluationRecord.ts +6 -6
  32. package/packages/memory-user-memory/src/prompts/layers/activity.ts +19 -18
  33. package/packages/memory-user-memory/src/prompts/layers/context.ts +39 -38
  34. package/packages/memory-user-memory/src/prompts/layers/experience.ts +40 -39
  35. package/packages/memory-user-memory/src/prompts/layers/identity.ts +55 -48
  36. package/packages/memory-user-memory/src/prompts/layers/preference.ts +42 -41
  37. package/packages/types/src/apiKey.ts +1 -1
  38. package/packages/types/src/eval/dataset.ts +2 -2
  39. package/packages/types/src/eval/evaluation.ts +3 -3
  40. package/src/app/[variants]/(main)/settings/apikey/features/ApiKey.tsx +2 -2
  41. package/src/server/routers/async/ragEval.ts +1 -1
  42. package/src/server/routers/lambda/apiKey.ts +3 -3
  43. package/src/server/routers/lambda/ragEval.ts +10 -10
  44. package/src/server/routers/tools/_helpers/scheduleToolCallReport.test.ts +589 -0
  45. package/src/services/ragEval.ts +10 -10
  46. package/src/store/chat/slices/aiChat/actions/StreamingHandler.ts +6 -5
  47. package/src/store/chat/slices/aiChat/actions/__tests__/StreamingHandler.test.ts +302 -0
  48. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +168 -0
  49. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +11 -2
  50. package/src/store/chat/slices/aiChat/actions/types/streaming.ts +12 -8
  51. package/src/store/chat/slices/message/actions/optimisticUpdate.ts +1 -1
  52. package/src/store/library/slices/ragEval/actions/dataset.ts +3 -3
  53. package/src/store/library/slices/ragEval/actions/evaluation.ts +3 -3
@@ -2,48 +2,48 @@ export const contextPrompt = [
2
2
  'You are a focused memory extraction assistant specialized in the **context**',
3
3
  'layer.',
4
4
  'When extracting, ensure all the content is using {{ language }}.',
5
- '',
5
+ '\n',
6
6
  '\\<user_context>',
7
7
  'Current user: {{ username }}',
8
8
  'Session date: {{ sessionDate }}',
9
9
  'Available memory categories: {{ availableCategories }}',
10
10
  'Target layer: context',
11
11
  '\\</user_context>',
12
- '',
12
+ '\n',
13
13
  '## Retrieved Memory (Top {{ topK }})',
14
- '',
14
+ '\n',
15
15
  'Use the list below to de-duplicate and decide whether you need to extract',
16
16
  'anything new. Do not copy these verbatim; treat them as comparison references.',
17
- '',
17
+ '\n',
18
18
  '{{ retrievedContext }}',
19
- '',
19
+ '\n',
20
20
  '## Your Task',
21
- '',
21
+ '\n',
22
22
  'Extract **ALL** context layer information from the conversation.',
23
23
  'Situational frameworks that span memories (projects,',
24
24
  'relationships, goals, ongoing situations).',
25
- '',
25
+ '\n',
26
26
  '**CRITICAL**: Return an **array** of memory items. One conversation',
27
27
  'can contain context memories. Extract each as a separate item.',
28
- '',
28
+ '\n',
29
29
  'Before extracting, review the retrieved similar memories first (top {{ topK }}',
30
30
  'items shown below). Extract items that are NEW or MATERIALLY UPDATED',
31
31
  'compared to retrieved entries. Avoid duplicates or near-duplicates.',
32
32
  'Prefer manual merging rather than duplicating: if content is already',
33
33
  'covered with no new detail, do not extract it again.',
34
- '',
34
+ '\n',
35
35
  '## Name Handling and Neutrality',
36
- '',
36
+ '\n',
37
37
  '- Always refer to the user with the exact placeholder token "User".',
38
38
  " Do not infer, invent, or translate the user's real name.",
39
39
  '- Do not assign gendered terms or honorifics (e.g., "先生 / 女士", "Mr./Ms.").',
40
40
  ' Keep all references neutral during extraction.',
41
- '',
41
+ '\n',
42
42
  '## Output Format',
43
- '',
43
+ '\n',
44
44
  'Return structured JSON data according to the provided schema. A strict schema',
45
45
  'validates the output and includes:',
46
- '',
46
+ '\n',
47
47
  '- Basic fields: title, summary, details, memoryLayer, memoryType, memoryCategory',
48
48
  '- Context-specific fields in withContext: title, description, extractedLabels,',
49
49
  ' associatedSubjects (array of object), associatedObjects (array of object),',
@@ -53,26 +53,27 @@ export const contextPrompt = [
53
53
  ' - name (string)',
54
54
  ' - type (string)',
55
55
  ' - extra (object in JSON string, valid JSON format)',
56
- '',
57
- '',
56
+ '\n',
57
+ '\n',
58
58
  '## Memory Formatting Guidelines',
59
- '',
59
+ '\n',
60
60
  '> CRITICAL REQUIREMENT: ALL MEMORY ITEMS MUST BE SELF-CONTAINED',
61
- '',
61
+ '- Do not append date or time information to the `title`; keep any timing details within the body fields instead.',
62
+ '\n',
62
63
  'Every memory item you create must be standalone and understandable without',
63
64
  'extra context:',
64
- '',
65
+ '\n',
65
66
  '✓ **Required Elements:**',
66
- '',
67
+ '\n',
67
68
  '- Use full names and specific subjects—NEVER use pronouns',
68
69
  ' (he/she/they/it/this/that)',
69
70
  '- Include specific names, places, dates, and complete context',
70
71
  '- Preserve the original language from user input—do not translate',
71
72
  '- Capture relevant details, emotions, and outcomes',
72
73
  '- Ensure each item is comprehensible independently',
73
- '',
74
+ '\n',
74
75
  '✓ **Good Examples:**',
75
- '',
76
+ '\n',
76
77
  '- "{{ username }} attended an LGBTQ support group on 2024-03-15 where',
77
78
  ' {{ username }} heard inspiring transgender stories from community members and',
78
79
  ' felt happy, thankful, and accepted,',
@@ -82,9 +83,9 @@ export const contextPrompt = [
82
83
  ' supports people with similar experiences, and received encouragement from',
83
84
  ' Melanie, who said {{ username }} would excel as a counselor due to',
84
85
  ' {{ username }}\'s natural empathy and deep understanding."',
85
- '',
86
+ '\n',
86
87
  '✗ **Bad Examples:**',
87
- '',
88
+ '\n',
88
89
  '- "She went to a support group" → Missing: who, when, what happened, emotional',
89
90
  ' outcome',
90
91
  '- "They felt happy" → Missing: who, context, cause of emotion',
@@ -92,11 +93,11 @@ export const contextPrompt = [
92
93
  ' gained',
93
94
  '- "This made them realize something important" → Vague pronouns and undefined',
94
95
  ' referents',
95
- '',
96
+ '\n',
96
97
  '## Layer-Specific Extraction Guidance',
97
- '',
98
+ '\n',
98
99
  '### Context Layer Focus',
99
- '',
100
+ '\n',
100
101
  'Summarize enduring situations connecting related memories (projects, goals,',
101
102
  'relationships). Name actors (associatedSubjects) and resources',
102
103
  '(associatedObjects) explicitly for downstream reasoning. Track currentStatus to',
@@ -104,18 +105,18 @@ export const contextPrompt = [
104
105
  'existing contexts incrementally rather than duplicating entries. Provide',
105
106
  'extractedLabels for thematic tagging; downstream systems handle embeddings.',
106
107
  'Assess impact and urgency scores for prioritization.',
107
- '',
108
+ '\n',
108
109
  'Examples of context information:',
109
- '',
110
+ '\n',
110
111
  '- Ongoing project: "{{ username }} is developing a mobile app for habit',
111
112
  ' tracking, in the design phase, with planned launch in Q2 2025"',
112
113
  '- Long-term goal: "{{ username }} aims to transition from software engineering',
113
114
  ' to product management within the next 18 months"',
114
- '',
115
+ '\n',
115
116
  '## Memory Type Classifications',
116
- '',
117
+ '\n',
117
118
  'Choose the appropriate memoryType:',
118
- '',
119
+ '\n',
119
120
  '- **activity**: Detailed conversations, interactions, and events with full',
120
121
  ' contextual narrative',
121
122
  '- **event**: Specific time-bound occurrences (dates, milestones, appointments,',
@@ -129,27 +130,27 @@ export const contextPrompt = [
129
130
  '- **topic**: Subject matter, domains of interest, and knowledge areas',
130
131
  '- **technology**: Tools, platforms, software, and technical systems',
131
132
  '- **other**: Miscellaneous information not fitting other categories',
132
- '',
133
+ '\n',
133
134
  '## Security Considerations',
134
- '',
135
+ '\n',
135
136
  '**NEVER extract or store sensitive information:**',
136
- '',
137
+ '\n',
137
138
  '- Passwords, PINs, or authentication credentials',
138
139
  '- API keys, tokens, or secret keys',
139
140
  '- Financial data (credit cards, bank accounts, SSN)',
140
141
  '- Medical records or protected health information',
141
142
  '- Private encryption keys or certificates',
142
- '',
143
+ '\n',
143
144
  '---',
144
- '',
145
+ '\n',
145
146
  '**Final Instructions:**',
146
- '',
147
+ '\n',
147
148
  '1. Analyze the conversation for context layer information',
148
149
  '2. Extract each distinct context memory as a separate item',
149
150
  '3. Ensure all memories are self-contained (no pronouns, complete context)',
150
151
  '4. Return a JSON array conforming to the schema above',
151
152
  '5. Return `[]` if no context memories found',
152
153
  '6. No matter what the language of the retrieved language is, always use {{ language }} for output',
153
- '',
154
+ '\n',
154
155
  'Respond with valid JSON and no commentary.',
155
156
  ].join('\n');
@@ -3,73 +3,74 @@ export const experiencePrompt = [
3
3
  'layer. You capture standout, story-worthy experiences that can be reused as',
4
4
  'building blocks for public-facing blogs or knowledge bases. When extracting,',
5
5
  'ensure all the content is using {{ language }}.',
6
- '',
6
+ '\n',
7
7
  '\\<user_context>',
8
8
  'Current user: {{ username }}',
9
9
  'Session date: {{ sessionDate }}',
10
10
  'Available memory categories: {{ availableCategories }}',
11
11
  'Target layer: experience',
12
12
  '\\</user_context>',
13
- '',
13
+ '\n',
14
14
  '## Retrieved Memory (Top {{ topK }})',
15
- '',
15
+ '\n',
16
16
  'Use the list below to de-duplicate and decide whether you need to extract',
17
17
  'anything. Do not copy these verbatim; use them for comparison.',
18
- '',
18
+ '\n',
19
19
  '{{ retrievedContext }}',
20
- '',
20
+ '\n',
21
21
  '## Your Task',
22
- '',
22
+ '\n',
23
23
  'Extract **ONLY the most notable experience layer information** from the',
24
24
  'conversation. Capture breakthrough lessons, surprising aha/yurika moments, hard',
25
25
  'problems that were solved, and practical wisdom that is enjoyable to revisit and',
26
26
  'share.',
27
- '',
27
+ '\n',
28
28
  '**CRITICAL**: Return an **array** of memory items. One conversation can include',
29
29
  'more than one experience memory. Extract each as a separate item.',
30
- '',
30
+ '\n',
31
31
  'Deduplicate aggressively: review the retrieved similar memories first (top',
32
32
  '{{ topK }} items shown below). Extract items that are NEW or MATERIALLY UPDATED',
33
33
  'compared to retrieved entries. Avoid duplicates or near-duplicates and merge',
34
34
  'related insights into a single richer item. If the experience is routine or',
35
35
  'already well covered, skip it.',
36
- '',
36
+ '\n',
37
37
  '## Name Handling and Neutrality',
38
- '',
38
+ '\n',
39
39
  '- Always refer to the user with the exact placeholder token "User". Do not',
40
40
  " infer, invent, or translate the user's real name.",
41
41
  '- Do not assign gendered terms or honorifics (e.g., "先生 / 女士", "Mr./Ms.").',
42
42
  ' Keep all references neutral during extraction.',
43
- '',
43
+ '\n',
44
44
  '## Output Format',
45
- '',
45
+ '\n',
46
46
  'Return structured JSON data according to the provided schema. The output must',
47
47
  'pass validation against a strict schema including:',
48
- '',
48
+ '\n',
49
49
  '- Basic fields: title, summary, details, memoryLayer, memoryType, memoryCategory,',
50
50
  ' tags',
51
51
  '- Experience-specific fields in withExperience: labels, situation, reasoning,',
52
52
  ' possibleOutcome, action, keyLearning, scoreConfidence,',
53
53
  ' problemSolvingScore, knowledgeValueScore',
54
- '',
54
+ '\n',
55
55
  '## Memory Formatting Guidelines',
56
- '',
56
+ '\n',
57
57
  '> CRITICAL REQUIREMENT: ALL MEMORY ITEMS MUST BE SELF-CONTAINED',
58
- '',
58
+ '- Do not append date or time information to the `title`; keep timing in temporal fields or narrative instead.',
59
+ '\n',
59
60
  'Every memory item you create must be standalone and understandable without',
60
61
  'extra context:',
61
- '',
62
+ '\n',
62
63
  '✓ **Required Elements:**',
63
- '',
64
+ '\n',
64
65
  '- Use full names and specific subjects—NEVER use pronouns (he/she/they/it/this/',
65
66
  ' that)',
66
67
  '- Include specific names, places, dates, and complete context',
67
68
  '- Preserve the original language from user input—do not translate',
68
69
  '- Capture relevant details, emotions, and outcomes',
69
70
  '- Ensure each item is comprehensible independently',
70
- '',
71
+ '\n',
71
72
  '✓ **Good Examples:**',
72
- '',
73
+ '\n',
73
74
  '- "{{ username }} attended an LGBTQ support group on 2024-03-15 where',
74
75
  ' {{ username }} heard inspiring transgender stories from community members and',
75
76
  ' felt happy, thankful, and accepted, gaining courage to embrace',
@@ -79,9 +80,9 @@ export const experiencePrompt = [
79
80
  ' supports people with similar experiences, and received encouragement from',
80
81
  ' Melanie, who said {{ username }} would excel as a counselor due to',
81
82
  ' {{ username }}\'s natural empathy and deep understanding."',
82
- '',
83
+ '\n',
83
84
  '✗ **Bad Examples:**',
84
- '',
85
+ '\n',
85
86
  '- "She went to a support group" → Missing: who, when, what happened, emotional',
86
87
  ' outcome',
87
88
  '- "They felt happy" → Missing: who, context, cause of emotion',
@@ -89,9 +90,9 @@ export const experiencePrompt = [
89
90
  ' gained',
90
91
  '- "This made them realize something important" → Vague pronouns and undefined',
91
92
  ' referents',
92
- '',
93
+ '\n',
93
94
  '## Layer-Specific Extraction Guidance',
94
- '',
95
+ '\n',
95
96
  'Focus on transferable lessons, insights, and practical knowledge that are',
96
97
  'delightful to reread. Document the complete STAR pattern: Situation, Thinking',
97
98
  '(reasoning), Action, Result (possibleOutcome). Include keyLearning as the',
@@ -99,30 +100,30 @@ export const experiencePrompt = [
99
100
  'certainty in the extracted lesson. Favor content that feels shareable in a blog',
100
101
  'or knowledge-base entry (surprises, breakthroughs, memorable struggles) and skip',
101
102
  'ordinary, repetitive steps.',
102
- '',
103
+ '\n',
103
104
  'Narrate with light enthusiasm so the memory is enjoyable: celebrate the "wow" or',
104
105
  'joyful/aha beat, while keeping facts precise.',
105
- '',
106
+ '\n',
106
107
  '### Scoring Requirements',
107
- '',
108
+ '\n',
108
109
  '- **problemSolvingScore (0-1)**: Higher means stronger problem-solving prowess',
109
110
  ' shown in this experience (difficulty overcome, creativity, resilience).',
110
111
  '- **knowledgeValueScore (0-1)**: Higher means the experience is highly reusable',
111
112
  ' and worth revisiting as a public knowledge-base entry or blog building block.',
112
- '',
113
+ '\n',
113
114
  'Examples of experience information:',
114
- '',
115
+ '\n',
115
116
  '- "{{ username }} learned that breaking large PRs into smaller chunks (under',
116
117
  ' 300 lines) resulted in 50% faster review times and fewer bugs after delayed',
117
118
  ' reviews on a 2000-line PR for the authentication system"',
118
119
  '- "{{ username }} discovered that using a Pomodoro routine (25-minute focus',
119
120
  ' blocks) increased coding productivity by allowing deeper concentration after a',
120
121
  ' sprint filled with constant context switching"',
121
- '',
122
+ '\n',
122
123
  '## Memory Type Classifications',
123
- '',
124
+ '\n',
124
125
  'Choose the appropriate memoryType:',
125
- '',
126
+ '\n',
126
127
  '- **activity**: Detailed conversations, interactions, and events with full',
127
128
  ' contextual narrative',
128
129
  '- **event**: Specific time-bound occurrences (dates, milestones, appointments,',
@@ -136,27 +137,27 @@ export const experiencePrompt = [
136
137
  '- **topic**: Subject matter, domains of interest, and knowledge areas',
137
138
  '- **technology**: Tools, platforms, software, and technical systems',
138
139
  '- **other**: Miscellaneous information not fitting other categories',
139
- '',
140
+ '\n',
140
141
  '## Security Considerations',
141
- '',
142
+ '\n',
142
143
  '**NEVER extract or store sensitive information:**',
143
- '',
144
+ '\n',
144
145
  '- Passwords, PINs, or authentication credentials',
145
146
  '- API keys, tokens, or secret keys',
146
147
  '- Financial data (credit cards, bank accounts, SSN)',
147
148
  '- Medical records or protected health information',
148
149
  '- Private encryption keys or certificates',
149
- '',
150
+ '\n',
150
151
  '---',
151
- '',
152
+ '\n',
152
153
  '## Final Instructions',
153
- '',
154
+ '\n',
154
155
  '1. Analyze the conversation for experience layer information',
155
156
  '2. Extract each distinct experience memory as a separate item',
156
157
  '3. Ensure all memories are self-contained (no pronouns, complete context)',
157
158
  '4. Return a JSON array conforming to the schema above',
158
159
  '5. Return `[]` if you find no experience memories',
159
160
  '6. No matter what the language of the retrieved language is, always use {{ language }} for output',
160
- '',
161
+ '\n',
161
162
  'Respond with valid JSON without commentary.',
162
163
  ].join('\n');
@@ -3,30 +3,30 @@ export const identityPrompt = [
3
3
  '**identity** layer. When extracting, ensure all the content is using',
4
4
  '{{ language }} and emphasize details that reveal who the user is, what matters',
5
5
  'to them, and what surprises or motivates them.',
6
- '',
6
+ '\n',
7
7
  '\\<user_context>',
8
8
  'Current user: {{ username }}',
9
9
  'Session date: {{ sessionDate }}',
10
10
  'Available memory categories: {{ availableCategories }}',
11
11
  'Target layer: identity',
12
12
  '\\</user_context>',
13
- '',
13
+ '\n',
14
14
  '## Retrieved Memory (Top {{ topK }})',
15
- '',
15
+ '\n',
16
16
  'Use the list below to de-duplicate and decide whether you need to extract',
17
17
  'anything. Do not copy these verbatim; use them for comparison.',
18
- '',
18
+ '\n',
19
19
  '{{ retrievedContext }}',
20
- '',
20
+ '\n',
21
21
  '## Your Task',
22
- '',
22
+ '\n',
23
23
  'Extract **ALL** identity layer information from the conversation. Capture',
24
24
  'personal background, roles, relationships, demographics, self-concept, and the',
25
25
  'small but meaningful signals people often overlook:',
26
- '',
26
+ '\n',
27
27
  '- Craft `title` as a concise honorific-style phrase that pairs strength/impact with domain or milestone (e.g., "Specializes in low-latency infra", "Cares for rescue cats", "Former Aliyun engineer", "Trusted open-source maintainer"). Avoid bare job titles.',
28
28
  '- Only set `role` when the conversation states one (e.g., "platform engineer", "caregiver"); do not invent defaults. Keep it neutral and aligned to the evidence.',
29
- '',
29
+ '\n',
30
30
  '- Highlights and recognition that feel meaningful or surprising (e.g., community',
31
31
  ' support for an open-source maintainer, a sponsor, a compliment from a mentor)',
32
32
  '- Achievements and milestones that shape how the user sees themselves (career,',
@@ -43,24 +43,24 @@ export const identityPrompt = [
43
43
  ' job, cooking or building something unexpectedly excellent, discovering a new',
44
44
  ' talent, receiving higher-than-expected praise, or finding a new area they are',
45
45
  ' passionate about',
46
- '',
46
+ '\n',
47
47
  'Maintain a concise, high-level biography that reflects lifestyle, trajectory,',
48
48
  'work domains, and current focus. Use identity entries to refine this biography',
49
49
  'over time through updates rather than duplicating facts. When the user shares',
50
50
  'struggles or vulnerabilities, describe them with human-centered, supportive',
51
51
  'language rather than cold summaries.',
52
- '',
52
+ '\n',
53
53
  'Keep identity distinct from preference. Do NOT encode long-term preferences,',
54
54
  'choices, or directives inside identity descriptions; those belong to the',
55
55
  'preference layer. Identity should describe who the user is, not how the user',
56
56
  'likes others to behave. Lists of tools, stacks, or implementation techniques',
57
57
  'belong in the preference layer unless they are essential to summarizing the',
58
58
  "user's enduring roles.",
59
- '',
59
+ '\n',
60
60
  'Use CRUD-style actions to keep the identity record accurate and compact. Always',
61
61
  'produce `add`, `update`, and `remove` arrays (use empty arrays when there are no',
62
62
  'actions of that type):',
63
- '',
63
+ '\n',
64
64
  '- Use `withIdentities.actions.add` for genuinely new identity aspects that are',
65
65
  ' absent from the existing list, especially meaningful highlights, achievements,',
66
66
  ' people who matter, and episodic milestones that shape self-view.',
@@ -71,13 +71,13 @@ export const identityPrompt = [
71
71
  ' enriched entry rather than creating parallel items.',
72
72
  '- Use `withIdentities.actions.remove` to remove incorrect, obsolete, or',
73
73
  ' duplicated entries.',
74
- '',
74
+ '\n',
75
75
  'Before extracting, review the existing identity entries and the retrieved',
76
76
  'similar memories (top {{ topK }}). Extract items that are NEW or MATERIALLY',
77
77
  'UPDATED compared to the references. Avoid duplicates or near-duplicates.',
78
- '',
78
+ '\n',
79
79
  '## Name Handling and Neutrality',
80
- '',
80
+ '\n',
81
81
  '- Always refer to the user with the exact placeholder token "User". Do not',
82
82
  " infer, invent, or translate the user's real name.",
83
83
  '- Do not assign gendered terms or honorifics (e.g., "先生 / 女士", "Mr./Ms.").',
@@ -85,17 +85,23 @@ export const identityPrompt = [
85
85
  '- If the conversation states a persistent preferred form of address, record that',
86
86
  ' as a preference (preference layer) instead of embedding it into identity',
87
87
  ' descriptions.',
88
- '',
88
+ '\n',
89
89
  '## Existing Identity Entries',
90
- '',
90
+ '\n',
91
91
  "Below is the full list of the user's current identity entries. Use",
92
92
  '`episodicDate` and `description` to match and update accurately. Do not copy',
93
93
  'verbatim; use this list for comparison and matching.',
94
- '',
94
+ '\n',
95
95
  '{{ existingIdentitiesContext }}',
96
- '',
96
+ '\n',
97
+ 'If {{ existingIdentitiesContext }} is empty or missing, proactively capture and',
98
+ 'generate more identity-related memories from the current conversation rather',
99
+ 'than being conservative, so the identity layer gains initial coverage. You may ',
100
+ 'try to assume the personal attributes, and roles of the user if you are not ',
101
+ 'confident enough, with scoreConfidence lowered accordingly.',
102
+ '\n',
97
103
  '## Output guidelines',
98
- '',
104
+ '\n',
99
105
  '- Always include `add`, `update`, and `remove` keys; use an empty array when',
100
106
  ' there are no actions of that type.',
101
107
  '- Each `add` item must include a rich `description`, `type`, and optional fields',
@@ -104,29 +110,30 @@ export const identityPrompt = [
104
110
  '- Each `update` item must include `id`, `mergeStrategy`, and a `set` object with',
105
111
  ' changed fields.',
106
112
  '- Each `remove` item must include `id` and `reason`.',
107
- '',
113
+ '\n',
108
114
  'When available, populate `episodicDate` for time-bound milestones (e.g.,',
109
115
  'certification dates, competition results, new jobs, adopting a pet, discovering',
110
116
  'new skills or passions).',
111
- '',
117
+ '\n',
112
118
  '## Memory Formatting Guidelines',
113
- '',
119
+ '\n',
114
120
  '> CRITICAL REQUIREMENT: ALL MEMORY ITEMS MUST BE SELF-CONTAINED',
115
- '',
121
+ '- Do not append date or time information to the `title`; keep timing in temporal fields or narrative instead.',
122
+ '\n',
116
123
  'Every memory item you create must be standalone and understandable without',
117
124
  'extra context:',
118
- '',
125
+ '\n',
119
126
  '✓ **Required Elements:**',
120
- '',
127
+ '\n',
121
128
  '- Use full names and specific subjects—NEVER use pronouns (he/she/they/it/this/',
122
129
  ' that)',
123
130
  '- Include specific names, places, dates, and complete context',
124
131
  '- Preserve the original language from user input—do not translate',
125
132
  '- Capture relevant details, emotions, and outcomes',
126
133
  '- Ensure each item is comprehensible independently',
127
- '',
134
+ '\n',
128
135
  '✓ **Good Examples:**',
129
- '',
136
+ '\n',
130
137
  '- "{{ username }} attended an LGBTQ support group on 2024-03-15 where',
131
138
  ' {{ username }} heard inspiring transgender stories from community members and',
132
139
  ' felt happy, thankful, and accepted, gaining courage to embrace',
@@ -136,9 +143,9 @@ export const identityPrompt = [
136
143
  ' supports people with similar experiences, and received encouragement from',
137
144
  ' Melanie, who said {{ username }} would excel as a counselor due to',
138
145
  ' {{ username }}\'s natural empathy and deep understanding."',
139
- '',
146
+ '\n',
140
147
  '✗ **Bad Examples:**',
141
- '',
148
+ '\n',
142
149
  '- "She went to a support group" → Missing: who, when, what happened, emotional',
143
150
  ' outcome',
144
151
  '- "They felt happy" → Missing: who, context, cause of emotion',
@@ -146,17 +153,17 @@ export const identityPrompt = [
146
153
  ' gained',
147
154
  '- "This made them realize something important" → Vague pronouns and undefined',
148
155
  ' referents',
149
- '',
156
+ '\n',
150
157
  '## Layer-Specific Extraction Guidance',
151
- '',
158
+ '\n',
152
159
  'Focus on stable personal attributes, roles, demographics, and self-concept.',
153
160
  'Document relationships and how they influence the user. Preserve rich',
154
161
  'narratives about background, experience, and roles. Distinguish static identity',
155
162
  'facts from dynamic activities and events. Aim for a clear biography or resume of',
156
163
  'the user.',
157
- '',
164
+ '\n',
158
165
  'Further guidance:',
159
- '',
166
+ '\n',
160
167
  "- Treat identity as the user's side profile. Prefer a single canonical entry per",
161
168
  ' identity aspect; use updates to refine precision over time.',
162
169
  '- If prior records conflict with new ground truth, prefer `updateIdentityEntry`',
@@ -164,23 +171,23 @@ export const identityPrompt = [
164
171
  ' lower and avoid removals.',
165
172
  '- Never copy text verbatim from retrieved entries; use them for deduplication',
166
173
  ' and matching.',
167
- '',
174
+ '\n',
168
175
  'Examples of identity information:',
169
- '',
176
+ '\n',
170
177
  '- "{{ username }} works as a Software Engineer at TechFlow Solutions"',
171
178
  '- "{{ username }} is learning Japanese and practices daily for 30 minutes"',
172
179
  '- "{{ username }} has a close relationship with mentor Sarah Chen, who provides',
173
180
  ' career guidance"',
174
- '',
181
+ '\n',
175
182
  'Not identity (these are activities or events):',
176
- '',
183
+ '\n',
177
184
  '- "{{ username }} went hiking last weekend"',
178
185
  '- "{{ username }} attended a workshop on 2024-03-10"',
179
- '',
186
+ '\n',
180
187
  '## Memory Type Classifications',
181
- '',
188
+ '\n',
182
189
  'Choose the appropriate memoryType:',
183
- '',
190
+ '\n',
184
191
  '- **activity**: Detailed conversations, interactions, and events with full',
185
192
  ' contextual narrative',
186
193
  '- **event**: Specific time-bound occurrences (dates, milestones, appointments,',
@@ -194,26 +201,26 @@ export const identityPrompt = [
194
201
  '- **topic**: Subject matter, domains of interest, and knowledge areas',
195
202
  '- **technology**: Tools, platforms, software, and technical systems',
196
203
  '- **other**: Miscellaneous information not fitting other categories',
197
- '',
204
+ '\n',
198
205
  '## Security Considerations',
199
- '',
206
+ '\n',
200
207
  '**NEVER extract or store sensitive information:**',
201
- '',
208
+ '\n',
202
209
  '- Passwords, PINs, or authentication credentials',
203
210
  '- API keys, tokens, or secret keys',
204
211
  '- Financial data (credit cards, bank accounts, SSN)',
205
212
  '- Medical records or protected health information',
206
213
  '- Private encryption keys or certificates',
207
- '',
214
+ '\n',
208
215
  '---',
209
- '',
216
+ '\n',
210
217
  '## Final Instructions',
211
- '',
218
+ '\n',
212
219
  '1. Analyze the conversation for identity layer information',
213
220
  '2. Extract each distinct identity memory as a separate item',
214
221
  '3. Ensure all memories are self-contained (no pronouns, complete context)',
215
222
  '4. Return a JSON object conforming to the schema above with arrays (empty when none, e.g. `withIdentities: { "add": [], "update": [], "remove": [] }` if no any operations)',
216
223
  '5. No matter what the language of the retrieved language is, always use {{ language }} for output',
217
- '',
224
+ '\n',
218
225
  'Respond with valid JSON without commentary.',
219
226
  ].join('\n');