ei-tui 0.1.25 → 0.2.0

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 (78) hide show
  1. package/README.md +42 -0
  2. package/package.json +1 -1
  3. package/src/README.md +4 -11
  4. package/src/cli/README.md +4 -5
  5. package/src/cli/retrieval.ts +3 -25
  6. package/src/cli.ts +3 -7
  7. package/src/core/AGENTS.md +1 -1
  8. package/src/core/constants/built-in-facts.ts +49 -0
  9. package/src/core/constants/index.ts +1 -0
  10. package/src/core/context-utils.ts +0 -1
  11. package/src/core/embedding-service.ts +8 -0
  12. package/src/core/handlers/dedup.ts +10 -16
  13. package/src/core/handlers/heartbeat.ts +2 -3
  14. package/src/core/handlers/human-extraction.ts +95 -30
  15. package/src/core/handlers/human-matching.ts +326 -248
  16. package/src/core/handlers/index.ts +8 -6
  17. package/src/core/handlers/persona-generation.ts +8 -8
  18. package/src/core/handlers/rewrite.ts +4 -29
  19. package/src/core/handlers/utils.ts +23 -1
  20. package/src/core/heartbeat-manager.ts +2 -4
  21. package/src/core/human-data-manager.ts +5 -27
  22. package/src/core/message-manager.ts +10 -10
  23. package/src/core/orchestrators/ceremony.ts +50 -39
  24. package/src/core/orchestrators/dedup-phase.ts +0 -1
  25. package/src/core/orchestrators/human-extraction.ts +351 -207
  26. package/src/core/orchestrators/index.ts +6 -4
  27. package/src/core/orchestrators/persona-generation.ts +3 -3
  28. package/src/core/processor.ts +99 -17
  29. package/src/core/prompt-context-builder.ts +4 -6
  30. package/src/core/state/human.ts +1 -26
  31. package/src/core/state/personas.ts +2 -2
  32. package/src/core/state-manager.ts +107 -14
  33. package/src/core/tools/builtin/read-memory.ts +7 -8
  34. package/src/core/types/data-items.ts +2 -4
  35. package/src/core/types/entities.ts +6 -4
  36. package/src/core/types/enums.ts +6 -9
  37. package/src/core/types/llm.ts +2 -2
  38. package/src/core/utils/crossFind.ts +2 -5
  39. package/src/core/utils/event-windows.ts +31 -0
  40. package/src/integrations/claude-code/importer.ts +8 -4
  41. package/src/integrations/claude-code/types.ts +2 -0
  42. package/src/integrations/opencode/importer.ts +7 -3
  43. package/src/prompts/AGENTS.md +73 -1
  44. package/src/prompts/ceremony/rewrite.ts +3 -22
  45. package/src/prompts/ceremony/types.ts +3 -3
  46. package/src/prompts/generation/descriptions.ts +2 -2
  47. package/src/prompts/generation/types.ts +2 -2
  48. package/src/prompts/heartbeat/types.ts +2 -2
  49. package/src/prompts/human/event-scan.ts +122 -0
  50. package/src/prompts/human/fact-find.ts +106 -0
  51. package/src/prompts/human/fact-scan.ts +0 -2
  52. package/src/prompts/human/index.ts +17 -10
  53. package/src/prompts/human/person-match.ts +65 -0
  54. package/src/prompts/human/person-scan.ts +52 -59
  55. package/src/prompts/human/person-update.ts +241 -0
  56. package/src/prompts/human/topic-match.ts +65 -0
  57. package/src/prompts/human/topic-scan.ts +51 -71
  58. package/src/prompts/human/topic-update.ts +295 -0
  59. package/src/prompts/human/types.ts +63 -40
  60. package/src/prompts/index.ts +4 -8
  61. package/src/prompts/persona/topics-update.ts +2 -2
  62. package/src/prompts/persona/traits.ts +2 -2
  63. package/src/prompts/persona/types.ts +3 -3
  64. package/src/prompts/response/index.ts +1 -1
  65. package/src/prompts/response/sections.ts +9 -12
  66. package/src/prompts/response/types.ts +2 -3
  67. package/src/storage/embeddings.ts +1 -1
  68. package/src/storage/index.ts +1 -0
  69. package/src/storage/indexed.ts +174 -0
  70. package/src/storage/merge.ts +67 -2
  71. package/tui/src/commands/me.tsx +5 -14
  72. package/tui/src/commands/settings.tsx +15 -0
  73. package/tui/src/context/ei.tsx +5 -14
  74. package/tui/src/util/yaml-serializers.ts +48 -33
  75. package/src/cli/commands/traits.ts +0 -25
  76. package/src/prompts/human/item-match.ts +0 -74
  77. package/src/prompts/human/item-update.ts +0 -364
  78. package/src/prompts/human/trait-scan.ts +0 -115
@@ -1,364 +0,0 @@
1
- import type { ItemUpdatePromptData, PromptOutput } from "./types.js";
2
- import type { DataItemBase } from "../../core/types.js";
3
- import { formatMessagesAsPlaceholders } from "../message-utils.js";
4
-
5
- const DESCRIPTION_MAX_CHARS = 500;
6
-
7
- function formatExistingItem(item: DataItemBase): string {
8
- return JSON.stringify({
9
- name: item.name,
10
- description: item.description,
11
- sentiment: item.sentiment,
12
- ...('strength' in item ? { strength: (item as any).strength } : {}),
13
- ...('relationship' in item ? { relationship: (item as any).relationship } : {}),
14
- ...('exposure_current' in item ? { exposure_current: (item as any).exposure_current } : {}),
15
- ...('exposure_desired' in item ? { exposure_desired: (item as any).exposure_desired } : {}),
16
- }, null, 2);
17
- }
18
-
19
- export function buildHumanItemUpdatePrompt(data: ItemUpdatePromptData): PromptOutput {
20
- if (!data.data_type || !data.persona_name) {
21
- throw new Error("buildHumanItemUpdatePrompt: data_type and persona_name are required");
22
- }
23
-
24
- const typeLabel = data.data_type.toUpperCase();
25
- const personaName = data.persona_name;
26
-
27
- const nameSection = data.data_type === "fact" ? `
28
- Should represent the _type_ of FACT, not the _value_ of the fact.
29
-
30
- Examples: "User's Name", "Birthday", "Birthplace", "Hometown", "Job", "Marital Status", "Eye Color", "Hair Color", "Nationality/Citizenship", "Languages Spoken", "Educational Background", "Wedding Anniversary", "Job Anniversary", "Pet Ownership", "Allergies", "Medical Conditions", "Dietary Restrictions"
31
-
32
- The only time we should be changing the name of a FACT is if it cannot fit into one of these _types_.
33
- `: `
34
- Should be a short identifier of the ${typeLabel}.
35
-
36
- Only update this field for clarification or if further specificity is warranted.
37
-
38
- Examples: "Unknown" -> "Brother-In-Law", "Alice's" -> "Alice's Restaurant"
39
- `;
40
-
41
- // This data isn't _specific_ to FACTS, but it only makes sense like this for them
42
- const itemFactType = data?.existing_item?.name || data.new_item_name;
43
- const traitDescriptionSection = `
44
- A brief characterization of how the Human demonstrates this trait. **1-2 sentences maximum.**
45
-
46
- ## CRITICAL: Traits are STABLE PATTERNS, not conversation logs
47
-
48
- A trait description captures the PATTERN, not the evidence for it.
49
-
50
- **Good description**: "Approaches problems methodically, breaking them into smaller components before tackling the whole."
51
- **Bad description**: "In this exchange, Jeremy demonstrated analytical thinking when he discussed the schema changes, and in the previous conversation he showed the same pattern when..."
52
-
53
- The description should:
54
- - State the trait pattern concisely
55
- - Focus on HOW the trait manifests in general terms
56
- - Be useful for a persona meeting this human for the first time
57
-
58
- The description should NOT:
59
- - Reference specific conversations or exchanges
60
- - Accumulate examples over time ("In this exchange... In this latest exchange...")
61
- - Include timestamps, dates, or temporal references
62
- - Exceed 2-3 sentences under any circumstances
63
-
64
- **Style**: Write as if describing the person to someone who hasn't met them. Brief, evergreen, pattern-focused.
65
-
66
- Examples:
67
- - "Prefers direct communication; appreciates when others get to the point quickly."
68
- - "Processes emotions internally before discussing them; may need time before opening up."
69
- `;
70
-
71
- const factDescriptionSection = `
72
- A concise, specific piece of information about the Human's ${itemFactType}.
73
-
74
- If ${itemFactType} doesn't make sense as a type of FACT, return an empty object (\`{}\`).
75
-
76
- If ${itemFactType} was misinterpreted (i.e., a joke, expression, or otherwise "not literally" a fact), return an empty object (\`{}\`).
77
-
78
- ## CRITICAL: Facts are OBJECTIVE
79
-
80
- FACTS are biographical/circumstantial data. NOT emotional interpretations.
81
-
82
- **Good description**: "Parents divorced twice. Second divorce occurred when user was 17/18."
83
- **Bad description**: "A deep, quiet ache related to mother's absence... a sacred absence shaped by love, loss, and quiet strength..."
84
-
85
- The description should record WHAT HAPPENED:
86
- - Dates, names, places, events, circumstances
87
- - What the user explicitly stated or clearly implied
88
-
89
- The description should NOT include:
90
- - Ei's poetic interpretation of emotional significance
91
- - Flowery language about "sacred absences" or "quiet aches"
92
- - Assumptions about how the user feels (that's what \`sentiment\` is for)
93
-
94
- If the user expressed emotion, quote or paraphrase THEIR words, don't embellish.
95
-
96
- **Style**: Be factual and concise. Record what the user said or demonstrated, not your interpretation of its deeper meaning. Avoid flowery or poetic language unless the user themselves used such language.
97
-
98
- Examples: "Name Unknown" -> "Robert Jordan", "User was married in the Summer" -> "User was married in July, 2006"
99
- `;
100
-
101
- const defaultDescriptionSection = `
102
- A concise, evergreen summary of what is currently known about this ${typeLabel}. Personas use this to recall context and make meaningful references.
103
-
104
- ## CRITICAL: Synthesize, don't accumulate
105
-
106
- Every update must **rewrite** the description as a current-state summary. Never append to it.
107
-
108
- **Good description**: "Active project to improve test coverage. Settled on Vitest + E2E harness. Currently focused on pipeline integration and extraction logic coverage."
109
- **Bad description**: "User asked Sisyphus to create a ticket... Later: pruned overengineered framework... Most recent session: added PR checks..."
110
-
111
- The description should:
112
- - Capture what is true NOW — the current state, decisions made, where things stand
113
- - Include details a persona would use to show genuine recall ("Oh right, you were working on the pipeline tests")
114
- - Be useful to a persona meeting this human for the first time
115
- - Read as a brief summary paragraph, not a session log
116
-
117
- The description should NOT:
118
- - Append "Most recent:", "Latest:", "Current session:", or any temporal marker
119
- - Accumulate a running history of every conversation that touched this ${typeLabel}
120
- - Reference specific ticket numbers, commit hashes, or PR numbers unless essential to meaning
121
- - Exceed 3-4 sentences under any circumstances
122
-
123
- **ABSOLUTELY VITAL**: Do **NOT** embellish — personas use their own voice. Capture what is true, not a log of how you got here.
124
- `;
125
-
126
- const descriptionSection =
127
- data.data_type === "fact" ? factDescriptionSection :
128
- data.data_type === "trait" ? traitDescriptionSection :
129
- defaultDescriptionSection;
130
-
131
- const strengthSection = data.data_type === "trait" ? `
132
- ## Strength (\`strength\`)
133
-
134
- How "strongly" the HUMAN USER shows this TRAIT.
135
-
136
- Use a scale of 0 to 1:
137
- - 0.0: The HUMAN USER is devoid of this trait
138
- - 0.5: The HUMAN USER shows this trait some of the time
139
- - 1.0: The HUMAN USER has this trait as a core aspect of their self
140
-
141
- Do not make micro-adjustments (0.4 -> 0.5). Close enough is OK for this field.` : '';
142
-
143
- const relationshipSection = data.data_type === "person" ? `
144
- ## Relationship (\`relationship\`)
145
-
146
- How the HUMAN USER is currently related to this PERSON.
147
-
148
- Once known, changes to this field are infrequent - A HUMAN USER's "Father" may be later clarified to "Step-Father", but is unlikely to become the user's "Uncle".
149
-
150
- Examples: "Unknown" -> "Coworker", "Mother" -> "Step-Mother", "Fiance" -> "Spouse"` : '';
151
-
152
- const categorySection = data.data_type === "topic" ? `
153
- ## Category (\`category\`)
154
-
155
- The type/category of this TOPIC. Pick the most appropriate from:
156
- - Interest: Hobbies, activities they enjoy
157
- - Goal: Things they want to achieve
158
- - Dream: Aspirational, maybe unrealistic desires
159
- - Conflict: Internal struggles, dilemmas
160
- - Concern: Worries, anxieties
161
- - Fear: Things that scare them
162
- - Hope: Positive expectations for the future
163
- - Plan: Concrete intentions
164
- - Project: Active undertakings
165
-
166
- If the topic doesn't fit neatly, pick the closest match.` : '';
167
-
168
- const exposureSection = (data.data_type === "topic" || data.data_type === "person") ? `
169
- ## Desired Exposure (\`exposure_desired\`)
170
-
171
- Represents how much the HUMAN USER wants to talk about this ${typeLabel}.
172
-
173
- Scale of 0.0 to 1.0:
174
- - 0.0: The HUMAN USER never wants to hear about this ${typeLabel}
175
- - 0.5: The HUMAN USER spends an average amount of time on this ${typeLabel}
176
- - 1.0: This ${typeLabel} is the sole focus of the HUMAN USER's existence
177
-
178
- Do not make micro-adjustments. Close enough is OK for this field.
179
-
180
- ## Exposure Impact (\`exposure_impact\`)
181
-
182
- This data point is NOT in the current data set, but it can be included in your return data.
183
-
184
- Exposure Impact measures how much exposure this conversation should count for:
185
- - "high": Long, detailed conversation exclusively about the ${typeLabel}
186
- - "medium": Long OR detailed conversation about the ${typeLabel}
187
- - "low": The conversation touched on this ${typeLabel} briefly
188
- - "none": The ${typeLabel} was only alluded to or hinted at
189
-
190
- This value adjusts the ongoing tracking of \`exposure_current\`.` : '';
191
-
192
- const currentDetailsSection = data.existing_item
193
- ? `\`\`\`json
194
- ${formatExistingItem(data.existing_item)}
195
- \`\`\`
196
-
197
- You are UPDATING an existing ${typeLabel}.`
198
- : `**NEW ${typeLabel} - NOT YET IN SYSTEM**
199
-
200
- You are CREATING a new ${typeLabel} from scratch based on what was discovered:
201
- \`\`\`json
202
- {
203
- "name": "${data.new_item_name || 'Uknown'}",
204
- "description": "${data.new_item_value || 'Details Unknown'}"
205
- }
206
- \`\`\`
207
-
208
- Return all fields for this ${typeLabel} based on what you find in the conversation.`;
209
-
210
- const jsonTemplateFields = [
211
- ' "name": "User\'s Name",',
212
- ' "description": "Their Actual Name",',
213
- ' "sentiment": 0.0',
214
- data.data_type === "trait" ? ',\n "strength": 0.5' : '',
215
- data.data_type === "person" ? ',\n "relationship": "Mother-In-Law|Son|Coworker|etc.",\n "exposure_desired": 0.4,\n "exposure_impact": "high|medium|low|none"' : '',
216
- data.data_type === "topic" ? ',\n "category": "Interest|Goal|Dream|Conflict|Concern|Fear|Hope|Plan|Project",\n "exposure_desired": 0.4,\n "exposure_impact": "high|medium|low|none"' : '',
217
- ',\n "quotes": [\n {\n "text": "exact phrase from message",\n "reason": "why this matters"\n }\n ]'
218
- ].filter(Boolean).join('');
219
-
220
- const system = `# Task
221
-
222
- You are scanning a conversation to deeply understand a ${typeLabel}.
223
-
224
- Your job is to take that analysis and apply it to the record we already have **IF DOING SO WILL PROVIDE THE HUMAN USER WITH A BETTER EXPERIENCE IN THE FUTURE**.
225
-
226
- This means that the detail you add should:
227
- 1. Be meaningful, accurate, or still true to the HUMAN USER in six months or more
228
- 2. **NOT** already be present in the description or name of the ${typeLabel}
229
-
230
- This ${typeLabel} will be recorded in the HUMAN USER's profile for agents and personas to later reference.
231
-
232
- # Field Definition and Explanation of Expected Changes
233
-
234
- ## Name (\`name\`)
235
- ${nameSection}
236
- ## Description (\`description\`)
237
- ${descriptionSection}
238
- ## Sentiment (\`sentiment\`)
239
-
240
- Represents how strongly the HUMAN USER feels about this ${typeLabel}.
241
-
242
- Scale of -1.0 to 1.0:
243
- - -1.0: There is no ${typeLabel} the HUMAN USER hates more
244
- - -0.5: The HUMAN USER does NOT like this ${typeLabel}, but recognizes some redeeming qualities
245
- - 0: The HUMAN USER has no feelings toward this ${typeLabel}
246
- - 0.5: The HUMAN USER enjoys this ${typeLabel}, but can recognize flaws
247
- - 1.0: This ${typeLabel} is the sole focus of the HUMAN USER's existence
248
-
249
- Do not make micro-adjustments. Close enough is OK for this field.
250
- ${strengthSection}${relationshipSection}${categorySection}${exposureSection}
251
-
252
- ## Quotes
253
-
254
- In addition to updating the ${typeLabel}, identify any **memorable, funny, important, or stand-out phrases** from the Most Recent Messages that relate to this ${typeLabel}.
255
-
256
- ### What Makes a Quote Worth Preserving
257
-
258
- **Prioritize:**
259
- - Humor, wit, colorful language, creative profanity
260
- - Emotional outbursts (positive or negative) — the raw stuff
261
- - Phrases that reveal personality or communication style
262
- - Things you'd quote back to them later to make them laugh
263
- - Unique expressions, malaphors, or turns of phrase
264
- - Quotable moments from EITHER speaker — humans AND AI personas both say memorable things
265
-
266
- **NEVER extract these — they are NOT quotes:**
267
- - Technical identifiers: ARNs, URLs, file paths, UUIDs, config keys, environment variable values, role/policy names
268
- - AI agent self-talk: "I notice I'm in Plan Mode", "I'll start by...", "Let me help you with...", status updates about the agent's own process
269
- - AI apologies or acknowledgments: "You're absolutely right", "I apologize for that overreach", "Good decision to revert"
270
- - Generic AI instructions or tips: "Remember to include X in your prompts", tool usage advice, workflow suggestions
271
- - Dry technical facts: infrastructure descriptions, process status, batch sizes, system architecture summaries
272
- - Status updates or process descriptions: "We're running a batch of...", "The pipeline is...", "I'm currently working on..."
273
- - Generic statements that could come from anyone or any AI session
274
- - Credentials, secrets, connection strings, or anything that looks like an access token
275
-
276
- **The litmus test**: Would you bring this up at a bar with a friend? Would it make someone laugh, think, or feel something?
277
- - "Does the Pope shit in his hat?" → YES. Hilarious malaphor.
278
- - "AWSReservedSSO_cmidp-nihl-sandbox-adm_db7b191e026bdd85" → NO. That's a credential.
279
- - "Slow is smooth. Smooth is fast." → YES (once). Pithy wisdom.
280
- - "The authentication flow is working correctly now" → NO. Status update.
281
- - "I built this, and now it's live." → YES. Pride and accomplishment.
282
-
283
- **When in doubt, leave it out.** An empty quotes array is always acceptable.
284
-
285
- Return them in the \`quotes\` array:
286
-
287
- \`\`\`json
288
- {
289
- "name": "...",
290
- "description": "...",
291
- "sentiment": 0.5,
292
- "quotes": [
293
- {
294
- "text": "exact phrase from the message",
295
- "reason": "why this is worth preserving"
296
- }
297
- ]
298
- }
299
- \`\`\`
300
-
301
- **CRITICAL**: Return the EXACT text as it appears in the message (spacing, punctuation, formatting, etc.). WE CAN ONLY USE IT IF WE FIND IT IN THE TEXT.
302
-
303
- # CRITICAL INSTRUCTIONS
304
-
305
- ONLY ANALYZE the "Most Recent Messages" in the following conversation. The "Earlier Conversation" is provided for your context and has already been processed!
306
-
307
- The JSON format is:
308
-
309
- \`\`\`json
310
- {
311
- ${jsonTemplateFields}
312
- }
313
- \`\`\`
314
-
315
- When you return a record, **ALWAYS** include every field (\`name\`, \`description\`, and \`sentiment\` are all REQUIRED fields).
316
-
317
- If you find **NO EVIDENCE** of this ${typeLabel} in the "Most Recent Messages", respond with an empty object: \`{}\`.
318
-
319
- If you determine **NO CHANGES** are required to the ${typeLabel}, respond with an empty object: \`{}\`.
320
-
321
- An empty object, \`{}\`, is the MOST COMMON expected response.
322
-
323
- # Current Details of ${typeLabel}
324
-
325
- ${currentDetailsSection}
326
- `;
327
-
328
- const earlierSection = data.messages_context.length > 0
329
- ? `## Earlier Conversation
330
- ${formatMessagesAsPlaceholders(data.messages_context, personaName)}
331
-
332
- `
333
- : '';
334
-
335
- const recentSection = `## Most Recent Messages
336
- ${formatMessagesAsPlaceholders(data.messages_analyze, personaName)}`;
337
-
338
- const user = `# Conversation
339
- ${earlierSection}${recentSection}
340
-
341
- ---
342
-
343
- Analyze the Most Recent Messages and update the ${typeLabel} if warranted.
344
-
345
- **Return JSON:**
346
- \`\`\`json
347
- {
348
- ${jsonTemplateFields}
349
- }
350
- \`\`\`
351
-
352
- If no changes are needed, respond with: \`{}\``;
353
-
354
- return { system, user };
355
- }
356
-
357
- /**
358
- * Truncate a description to DESCRIPTION_MAX_CHARS for use in prompts.
359
- * The stored value is unchanged — this only affects what goes into the LLM context.
360
- */
361
- export function truncateDescription(description: string): string {
362
- if (description.length <= DESCRIPTION_MAX_CHARS) return description;
363
- return description.slice(0, DESCRIPTION_MAX_CHARS) + "…";
364
- }
@@ -1,115 +0,0 @@
1
- import type { TraitScanPromptData, PromptOutput } from "./types.js";
2
- import { formatMessagesAsPlaceholders } from "../message-utils.js";
3
-
4
- export function buildHumanTraitScanPrompt(data: TraitScanPromptData): PromptOutput {
5
- if (!data.persona_name) {
6
- throw new Error("buildHumanTraitScanPrompt: persona_name is required");
7
- }
8
-
9
- const personaName = data.persona_name;
10
-
11
- const taskFragment = `# Task
12
-
13
- You are scanning a conversation to quickly identify important TRAITS of the HUMAN USER. Your ONLY job is to spot admissions, observations, or other indicators of TRAITS. Do NOT analyze them deeply. Just detect and flag.`;
14
-
15
- const specificNeedsFragment = `## Specific Needs
16
-
17
- Your job is to quickly identify:
18
- 1. Which TRAITS were mentioned or observed
19
- a. Only flag TRAITS that were actually discussed, not just tangentially related
20
- b. Be CONSERVATIVE - only suggest genuinely important, long-term relevant TRAITS
21
- i. Ignore: greetings, small talk, one-off mentions, jokes
22
- c. Be CLEAR - state your \`reason\` for including this TRAIT with any evidence you used`;
23
-
24
- const guidelinesFragment = `## Guidelines
25
-
26
- **A TRAIT Is:**
27
- * type_of_trait: Personality Patterns
28
- * Values: Introverted, Reserved, Extroverted, Detail Oriented, Analytical
29
- * type_of_trait: Communication Style
30
- * Assertive, Passive, Empathetic, Curious, Narrative
31
- * type_of_trait: Behavioral Tendencies
32
- * Risk-Taker, Cautious, Spontaneous, Decisive
33
- * type_of_trait: Cognitive Style / Learning Approach
34
- * Logical, Creative, Intuitive, Visual Learner
35
- * type_of_trait: Emotional Traits / Regulation
36
- * Emotionally Resilient, Optimistic, Pessimistic, Calm, Anxious
37
- * type_of_trait: Work Ethic / Task Orientation
38
- * Diligent, Proactive, Organized, Ambitious, Persistent
39
- * type_of_trait: Social Orientation
40
- * Collaborative, Independent, Competitive, Supportive, Gregarious
41
- * type_of_trait: Approach to Change & Adversity
42
- * Adaptable, Resilient, Flexible, Open-minded
43
- * type_of_trait: Motivational Drivers
44
- * Achievement-Oriented, Altruistic, Curiosity-Driven
45
- * type_of_trait: Ethical & Moral Stance
46
- * Principled, Honest, Integrity-Driven, Fair-minded
47
-
48
- **A TRAIT Is NOT:**
49
- - Biographical data: Name, Nickname, Birthday, Location, Job, Marital Status, Gender, Eye Color, Hair Color
50
- - Other unchangeable Data: Wedding Day, Allergies
51
- - General Topic: Interests, hobbies
52
- - People: Real people in their life: Wife, Husband, Daughter, Son, etc.
53
- - Personas: AI personas they discuss
54
- - Characters: Fictitious entities from books, movies, stories, media, etc.`;
55
-
56
- const criticalFragment = `# CRITICAL INSTRUCTIONS
57
-
58
- ONLY ANALYZE the "Most Recent Messages" in the following conversation. The "Earlier Conversation" is provided for your context and has already been processed!
59
-
60
- The JSON format is:
61
-
62
- \`\`\`json
63
- {
64
- "traits": [
65
- {
66
- "type_of_trait": "The type of trait from the list above",
67
- "value_of_trait": "A short description of the trait",
68
- "reason": "The justification of including this specific trait"
69
- }
70
- ]
71
- }
72
- \`\`\`
73
-
74
- **Return JSON only.**`;
75
-
76
- const system = `${taskFragment}
77
-
78
- ${specificNeedsFragment}
79
-
80
- ${guidelinesFragment}
81
-
82
- ${criticalFragment}`;
83
-
84
- const earlierSection = data.messages_context.length > 0
85
- ? `## Earlier Conversation
86
- ${formatMessagesAsPlaceholders(data.messages_context, personaName)}
87
-
88
- `
89
- : '';
90
-
91
- const recentSection = `## Most Recent Messages
92
- ${formatMessagesAsPlaceholders(data.messages_analyze, personaName)}`;
93
-
94
- const user = `# Conversation
95
- ${earlierSection}${recentSection}
96
-
97
- ---
98
-
99
- Scan the "Most Recent Messages" for TRAITS of the human user.
100
-
101
- **Return JSON:**
102
- \`\`\`json
103
- {
104
- "traits": [
105
- {
106
- "type_of_trait": "The type of trait from the list above",
107
- "value_of_trait": "A short description of the trait",
108
- "reason": "The justification of including this specific trait"
109
- }
110
- ]
111
- }
112
- \`\`\``;
113
-
114
- return { system, user };
115
- }