@auxiora/personality 1.3.0 → 1.10.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 (73) hide show
  1. package/dist/__tests__/architect-awareness-collector.test.js +42 -0
  2. package/dist/__tests__/architect-awareness-collector.test.js.map +1 -1
  3. package/dist/architect-awareness-collector.d.ts +6 -0
  4. package/dist/architect-awareness-collector.d.ts.map +1 -1
  5. package/dist/architect-awareness-collector.js +16 -0
  6. package/dist/architect-awareness-collector.js.map +1 -1
  7. package/dist/architect-bridge.d.ts +4 -0
  8. package/dist/architect-bridge.d.ts.map +1 -1
  9. package/dist/architect-bridge.js +9 -2
  10. package/dist/architect-bridge.js.map +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/lib/custom-weights.d.ts +7 -1
  14. package/lib/custom-weights.js +17 -0
  15. package/lib/decision-log.d.ts +41 -0
  16. package/lib/decision-log.js +145 -0
  17. package/lib/feedback-store.d.ts +45 -0
  18. package/lib/feedback-store.js +152 -0
  19. package/lib/index.d.ts +33 -160
  20. package/lib/index.d.ts.map +1 -1
  21. package/lib/index.js +31 -483
  22. package/lib/index.js.map +1 -1
  23. package/lib/persistence.d.ts +6 -0
  24. package/lib/persistence.js +9 -2
  25. package/lib/preference-history.d.ts +45 -0
  26. package/lib/preference-history.js +132 -0
  27. package/lib/schema.d.ts +6 -0
  28. package/lib/schema.d.ts.map +1 -1
  29. package/lib/system-prompt.js +11 -1
  30. package/lib/the-architect/context-detector.js.map +1 -1
  31. package/lib/the-architect/conversation-context.d.ts.map +1 -0
  32. package/lib/the-architect/conversation-export.d.ts.map +1 -0
  33. package/lib/the-architect/conversation-export.js.map +1 -0
  34. package/lib/the-architect/custom-weights.d.ts +7 -1
  35. package/lib/the-architect/custom-weights.d.ts.map +1 -0
  36. package/lib/the-architect/custom-weights.js +17 -0
  37. package/lib/the-architect/custom-weights.js.map +1 -0
  38. package/lib/the-architect/decision-log.d.ts +41 -0
  39. package/lib/the-architect/decision-log.d.ts.map +1 -0
  40. package/lib/the-architect/decision-log.js +145 -0
  41. package/lib/the-architect/decision-log.js.map +1 -0
  42. package/lib/the-architect/emotional-tracker.d.ts.map +1 -0
  43. package/lib/the-architect/emotional-tracker.js.map +1 -0
  44. package/lib/the-architect/feedback-store.d.ts +45 -0
  45. package/lib/the-architect/feedback-store.d.ts.map +1 -0
  46. package/lib/the-architect/feedback-store.js +152 -0
  47. package/lib/the-architect/feedback-store.js.map +1 -0
  48. package/lib/the-architect/index.d.ts +48 -5
  49. package/lib/the-architect/index.d.ts.map +1 -1
  50. package/lib/the-architect/index.js +142 -8
  51. package/lib/the-architect/index.js.map +1 -1
  52. package/lib/the-architect/persistence-adapter.d.ts.map +1 -0
  53. package/lib/the-architect/persistence-adapter.js.map +1 -0
  54. package/lib/the-architect/persistence.d.ts +6 -0
  55. package/lib/the-architect/persistence.d.ts.map +1 -0
  56. package/lib/the-architect/persistence.js +9 -2
  57. package/lib/the-architect/persistence.js.map +1 -0
  58. package/lib/the-architect/preference-history.d.ts +45 -0
  59. package/lib/the-architect/preference-history.d.ts.map +1 -0
  60. package/lib/the-architect/preference-history.js +132 -0
  61. package/lib/the-architect/preference-history.js.map +1 -0
  62. package/lib/the-architect/recommender.d.ts.map +1 -0
  63. package/lib/the-architect/recommender.js.map +1 -0
  64. package/lib/the-architect/system-prompt.d.ts.map +1 -1
  65. package/lib/the-architect/system-prompt.js +11 -1
  66. package/lib/the-architect/system-prompt.js.map +1 -1
  67. package/lib/the-architect/user-model-synthesizer.d.ts +100 -0
  68. package/lib/the-architect/user-model-synthesizer.d.ts.map +1 -0
  69. package/lib/the-architect/user-model-synthesizer.js +224 -0
  70. package/lib/the-architect/user-model-synthesizer.js.map +1 -0
  71. package/lib/user-model-synthesizer.d.ts +100 -0
  72. package/lib/user-model-synthesizer.js +224 -0
  73. package/package.json +4 -4
package/lib/index.js CHANGED
@@ -1,486 +1,34 @@
1
1
  // ────────────────────────────────────────────────────────────────────────────
2
- // THE ARCHITECT Full Data Flow (Phases 1–4)
3
- // ────────────────────────────────────────────────────────────────────────────
4
- //
5
- // ┌─ INBOUND ──────────────────────────────────────────────────────────────┐
6
- // │ User types message in chat UI │
7
- // │ ↓ │
8
- // │ Chat service calls architect.generatePrompt(userMessage, history) │
9
- // └───────────────────────────────────────────────────────────────────────┘
10
- //
11
- // ┌─ CONTEXT DETECTION (Phase 1 + Phase 2 corrections) ───────────────────┐
12
- // │ 1. detectContext() scores message against 17 domain keyword sets │
13
- // │ 2. CorrectionStore checks for learned corrections from past │
14
- // │ misclassifications — if a correction matches, it overrides the │
15
- // │ auto-detected domain and sets corrected=true, originalDomain │
16
- // │ 3. Emotional register inferred (neutral/stressed/frustrated/etc.) │
17
- // │ 4. Stakes, complexity, and mode derived from signals │
18
- // │ Result: TaskContext { domain, emotionalRegister, stakes, ... } │
19
- // └───────────────────────────────────────────────────────────────────────┘
20
- // ↓
21
- // ┌─ CONVERSATION THEME (Phase 3) ────────────────────────────────────────┐
22
- // │ 5. ConversationContext.recordDetection() adds to sliding window │
23
- // │ 6. After 3+ consistent detections, a theme locks in │
24
- // │ 7. Brief tangents (< 0.7 confidence) don't break theme │
25
- // │ 8. Crisis domains always override regardless of theme │
26
- // │ Result: effectiveDomain (may differ from raw detection) │
27
- // └───────────────────────────────────────────────────────────────────────┘
28
- // ↓
29
- // ┌─ TRAIT MIXING (Phases 1–4) ───────────────────────────────────────────┐
30
- // │ 9. baseMix = CONTEXT_PROFILES[effectiveDomain] (29 traits, 0–1) │
31
- // │ 10. adjustedMix = applyEmotionalOverride(baseMix, emotion) │
32
- // │ — stressed → +warmth, +stoicCalm, +empathy │
33
- // │ — frustrated → +empathy, +patience, -urgency │
34
- // │ — etc. │
35
- // │ 11. EmotionalTracker records intensity, detects trajectory │
36
- // │ (stable / escalating / de_escalating / volatile / shifting) │
37
- // │ 12. adjustedMix = applyTrajectoryMultipliers(adjustedMix, trajectory)│
38
- // │ — escalating: 1.2× warmth, empathy, calm │
39
- // │ — volatile: 1.3× warmth, calm │
40
- // │ 13. adjustedMix = customWeights.apply(adjustedMix) │
41
- // │ — additive offsets [-0.3, +0.3] from user preferences / presets │
42
- // │ Result: final TraitMix with all 29 traits modulated │
43
- // └───────────────────────────────────────────────────────────────────────┘
44
- // ↓
45
- // ┌─ PROMPT ASSEMBLY (Phase 1) ───────────────────────────────────────────┐
46
- // │ 14. contextModifier = assemblePromptModifier(adjustedMix, context) │
47
- // │ — weight-scaled behavioral instructions for each active trait │
48
- // │ 15. activeSources = getActiveSources(adjustedMix) │
49
- // │ — provenance: trait → historical mind → source work → evidence │
50
- // │ 16. fullPrompt = ARCHITECT_BASE_PROMPT + contextModifier │
51
- // │ Result: PromptOutput { fullPrompt, activeTraits, detectedContext } │
52
- // └───────────────────────────────────────────────────────────────────────┘
53
- // ↓
54
- // ┌─ SIDE EFFECTS (Phases 2–3) ───────────────────────────────────────────┐
55
- // │ 17. Fire-and-forget: persistence.recordUsage(domain) │
56
- // │ 18. Recommender checks for context suggestions: │
57
- // │ — correction_pattern: previously corrected similar messages │
58
- // │ — low_confidence: detection score below threshold │
59
- // │ — usage_pattern: unusual domain for this user │
60
- // │ Result: optional ContextRecommendation in output │
61
- // └───────────────────────────────────────────────────────────────────────┘
62
- // ↓
63
- // ┌─ OUTBOUND ────────────────────────────────────────────────────────────┐
64
- // │ Runtime sends fullPrompt as system prompt to AI provider │
65
- // │ Response displayed in chat UI with: │
66
- // │ — ContextIndicator pill (domain + emoji) │
67
- // │ — SourcesButton → SourcesPanel (active traits + provenance) │
68
- // │ — ContextRecommendation banner (if recommendation present) │
69
- // │ — ContextOverrideMenu (user can force a different domain) │
70
- // │ — TraitCustomizer (user adjusts trait weights / loads presets) │
71
- // │ — ConversationExportButton → JSON / Markdown / CSV download │
72
- // └───────────────────────────────────────────────────────────────────────┘
2
+ // Personality engine barrel export
73
3
  //
74
- // ────────────────────────────────────────────────────────────────────────────
75
- import { ARCHITECT_BASE_PROMPT } from './system-prompt.js';
76
- import { CONTEXT_PROFILES } from './context-profiles.js';
77
- import { applyEmotionalOverride } from './emotional-overrides.js';
78
- import { detectContext } from './context-detector.js';
79
- import { assemblePromptModifier, getActiveSources } from './prompt-assembler.js';
80
- import { CorrectionStore } from './correction-store.js';
81
- import { ArchitectPersistence } from './persistence.js';
82
- import { ContextRecommender } from './recommender.js';
83
- import { ConversationContext } from './conversation-context.js';
84
- import { EmotionalTracker, estimateIntensity } from './emotional-tracker.js';
85
- import { CustomWeights, WEIGHT_PRESETS } from './custom-weights.js';
86
- import { ConversationExporter } from './conversation-export.js';
87
- // Re-export building blocks for advanced consumers
88
- export { ARCHITECT_BASE_PROMPT } from './system-prompt.js';
89
- export { CONTEXT_PROFILES } from './context-profiles.js';
90
- export { EMOTIONAL_OVERRIDES, applyEmotionalOverride } from './emotional-overrides.js';
91
- export { detectContext, scoreAllDomains } from './context-detector.js';
92
- export { assemblePromptModifier, getActiveSources } from './prompt-assembler.js';
93
- export { SOURCE_MAP } from './source-map.js';
94
- export { TRAIT_TO_INSTRUCTION } from './trait-to-instruction.js';
95
- export { CorrectionStore } from './correction-store.js';
96
- export { ContextRecommender } from './recommender.js';
97
- export { ConversationContext } from './conversation-context.js';
98
- export { EmotionalTracker, estimateIntensity } from './emotional-tracker.js';
99
- export { CustomWeights, WEIGHT_PRESETS } from './custom-weights.js';
100
- export { ConversationExporter } from './conversation-export.js';
101
- export { ArchitectPersistence } from './persistence.js';
102
- export { InMemoryEncryptedStorage, VaultStorageAdapter } from './persistence-adapter.js';
103
- // ────────────────────────────────────────────────────────────────────────────
104
- // Domain metadata
105
- // ────────────────────────────────────────────────────────────────────────────
106
- const DOMAIN_METADATA = [
107
- { domain: 'security_review', label: 'Security Review', description: 'Adversarial analysis, threat modeling, vulnerability assessment' },
108
- { domain: 'code_engineering', label: 'Code Engineering', description: 'Writing, refactoring, testing, and deploying code' },
109
- { domain: 'architecture_design', label: 'Architecture Design', description: 'System design, trade-off analysis, pattern selection' },
110
- { domain: 'debugging', label: 'Debugging', description: 'Root cause analysis, mental execution tracing, fix verification' },
111
- { domain: 'team_leadership', label: 'Team Leadership', description: 'Culture building, standard setting, team performance' },
112
- { domain: 'one_on_one', label: 'One-on-One', description: 'Personal coaching, career development, empathetic listening' },
113
- { domain: 'sales_pitch', label: 'Sales Pitch', description: 'Value communication, transformation framing, objection handling' },
114
- { domain: 'negotiation', label: 'Negotiation', description: 'Tactical empathy, position analysis, leverage assessment' },
115
- { domain: 'marketing_content', label: 'Marketing Content', description: 'Positioning, messaging, audience-first content creation' },
116
- { domain: 'strategic_planning', label: 'Strategic Planning', description: 'Roadmap design, resource allocation, initiative prioritization' },
117
- { domain: 'crisis_management', label: 'Crisis Management', description: 'Incident response, stakeholder communication, rapid stabilization' },
118
- { domain: 'creative_work', label: 'Creative Work', description: 'Brainstorming, ideation, constraint-driven innovation' },
119
- { domain: 'writing_content', label: 'Writing Content', description: 'Drafting, editing, tone calibration, audience-aware prose' },
120
- { domain: 'decision_making', label: 'Decision Making', description: 'Option analysis, probability assessment, regret minimization' },
121
- { domain: 'personal_development', label: 'Personal Development', description: 'Career pathing, skill development, growth coaching' },
122
- { domain: 'learning_research', label: 'Learning & Research', description: 'Concept explanation, deep dives, teaching from first principles' },
123
- { domain: 'general', label: 'General', description: 'Balanced baseline for unclassified or mixed-domain conversations' },
124
- ];
125
- // ────────────────────────────────────────────────────────────────────────────
126
- // The Architect
127
- // ────────────────────────────────────────────────────────────────────────────
128
- /**
129
- * The Architect personality engine.
130
- *
131
- * Takes a user message and optional conversation history, detects the
132
- * operational context, selects and modulates traits, and assembles a
133
- * complete prompt with full provenance for every active trait.
134
- *
135
- * When constructed with an EncryptedStorage instance, persistence is enabled:
136
- * corrections, usage history, and preferences are stored encrypted at rest.
137
- * Call `initialize()` once after construction to load persisted state.
138
- */
139
- export class TheArchitect {
140
- contextOverride = null;
141
- correctionStore;
142
- recommender;
143
- conversationContext;
144
- emotionalTracker;
145
- customWeights;
146
- persistence;
147
- preferences;
148
- initialized = false;
149
- constructor(storage) {
150
- this.correctionStore = new CorrectionStore();
151
- this.recommender = new ContextRecommender();
152
- this.conversationContext = new ConversationContext();
153
- this.emotionalTracker = new EmotionalTracker();
154
- this.customWeights = new CustomWeights();
155
- if (storage) {
156
- this.persistence = new ArchitectPersistence(storage);
157
- }
158
- }
159
- /**
160
- * Load persisted state (corrections, preferences, usage history).
161
- * Call once after construction. Safe to call multiple times (idempotent).
162
- * No-op when persistence is not configured.
163
- */
164
- async initialize() {
165
- if (this.initialized || !this.persistence)
166
- return;
167
- const prefs = await this.persistence.load();
168
- this.correctionStore = CorrectionStore.deserialize(prefs.corrections);
169
- this.preferences = prefs;
170
- if (prefs.defaultContext) {
171
- this.contextOverride = prefs.defaultContext;
172
- }
173
- if (prefs.customWeights) {
174
- this.customWeights = CustomWeights.deserialize(prefs.customWeights);
175
- }
176
- this.initialized = true;
177
- }
178
- /**
179
- * Primary method: user message in, complete prompt out.
180
- *
181
- * Detects context, selects the domain profile, applies emotional
182
- * overrides, assembles a weight-scaled prompt modifier, and returns
183
- * the full prompt with active trait sources for transparency.
184
- *
185
- * Also records usage asynchronously (fire-and-forget) and checks
186
- * the recommender for context suggestions.
187
- */
188
- generatePrompt(userMessage, history) {
189
- const rawContext = this.detectContext(userMessage, history);
190
- let context;
191
- if (this.contextOverride) {
192
- context = { ...rawContext, domain: this.contextOverride, corrected: undefined, originalDomain: undefined };
193
- }
194
- else {
195
- // Apply conversation-level theme awareness
196
- const rawDomain = rawContext.domain;
197
- const rawConfidence = rawContext.detectionConfidence ?? 0;
198
- this.conversationContext.recordDetection(userMessage, rawDomain, rawConfidence);
199
- const effectiveDomain = this.conversationContext.getEffectiveDomain(rawDomain, rawConfidence);
200
- const theme = this.conversationContext.getSummary().theme;
201
- if (effectiveDomain !== rawDomain) {
202
- context = {
203
- ...rawContext,
204
- domain: effectiveDomain,
205
- rawDetectedDomain: rawDomain,
206
- themeOverridden: true,
207
- conversationTheme: theme ?? undefined,
208
- };
209
- }
210
- else {
211
- context = { ...rawContext, conversationTheme: theme ?? undefined };
212
- }
213
- }
214
- const baseMix = CONTEXT_PROFILES[context.domain];
215
- let adjustedMix = applyEmotionalOverride(baseMix, context.emotionalRegister);
216
- // Track emotional trajectory and apply trajectory-based multipliers
217
- const intensity = estimateIntensity(userMessage, context.emotionalRegister);
218
- this.emotionalTracker.recordEmotion(context.emotionalRegister, intensity, userMessage);
219
- const effective = this.emotionalTracker.getEffectiveEmotion();
220
- adjustedMix = this.applyTrajectoryMultipliers(adjustedMix, effective.trajectory);
221
- // Apply user's custom trait weight adjustments (additive offsets)
222
- adjustedMix = this.customWeights.apply(adjustedMix);
223
- const modifier = assemblePromptModifier(adjustedMix, context);
224
- const sources = getActiveSources(adjustedMix);
225
- // Fire-and-forget persistence of usage
226
- if (this.persistence) {
227
- this.persistence.recordUsage(context.domain).catch(() => { });
228
- }
229
- // Check for recommendations (only when no manual override is active)
230
- let recommendation;
231
- if (!this.contextOverride) {
232
- const usageHistory = this.preferences?.contextUsageHistory ?? {};
233
- recommendation = this.recommender.shouldRecommend(context, this.correctionStore, usageHistory, userMessage) ?? undefined;
234
- }
235
- return {
236
- basePrompt: ARCHITECT_BASE_PROMPT,
237
- contextModifier: modifier,
238
- fullPrompt: ARCHITECT_BASE_PROMPT + '\n\n' + modifier,
239
- activeTraits: sources,
240
- detectedContext: context,
241
- emotionalTrajectory: effective.trajectory,
242
- escalationAlert: effective.escalationAlert || undefined,
243
- recommendation,
244
- };
245
- }
246
- /**
247
- * Detects the full task context from a user message and optional
248
- * conversation history. Exposed publicly for debugging and testing.
249
- */
250
- detectContext(userMessage, history) {
251
- return detectContext(userMessage, history, this.correctionStore);
252
- }
253
- /**
254
- * Returns the fully modulated trait mix for a given context.
255
- * Applies the domain's base profile and then emotional overrides.
256
- */
257
- getTraitMix(context) {
258
- const base = CONTEXT_PROFILES[context.domain];
259
- return applyEmotionalOverride(base, context.emotionalRegister);
260
- }
261
- /** Returns the static base personality prompt. */
262
- getBasePrompt() {
263
- return ARCHITECT_BASE_PROMPT;
264
- }
265
- /**
266
- * Forces a specific domain regardless of context detection.
267
- * Pass `null` to return to automatic detection.
268
- */
269
- setContextOverride(domain) {
270
- this.contextOverride = domain;
271
- }
272
- /**
273
- * Returns all 17 context domains with human-readable labels
274
- * and one-line descriptions for UI rendering.
275
- */
276
- listContextDomains() {
277
- return DOMAIN_METADATA;
278
- }
279
- /**
280
- * Returns the active trait sources for the given mix, or for
281
- * the general profile if no mix is provided.
282
- */
283
- getActiveSources(mix) {
284
- const m = mix ?? CONTEXT_PROFILES['general'];
285
- return getActiveSources(m);
286
- }
287
- // ── Conversation context ─────────────────────────────────────────────
288
- /** Reset conversation context and emotional tracker for a new conversation. */
289
- resetConversation() {
290
- this.conversationContext.reset();
291
- this.emotionalTracker.reset();
292
- }
293
- /** Get the conversation context summary. */
294
- getConversationSummary() {
295
- return this.conversationContext.getSummary();
296
- }
297
- /** Get the current emotional trajectory. */
298
- getEmotionalState() {
299
- return this.emotionalTracker.getEffectiveEmotion();
300
- }
301
- // ── Custom weights ───────────────────────────────────────────────────
302
- /** Set a custom trait weight offset. Persists if storage is available. */
303
- async setTraitOverride(trait, offset) {
304
- this.customWeights.setOverride(trait, offset);
305
- await this.persistCustomWeights();
306
- }
307
- /** Remove a custom trait weight override. */
308
- async removeTraitOverride(trait) {
309
- this.customWeights.removeOverride(trait);
310
- await this.persistCustomWeights();
311
- }
312
- /** Load a preset weight configuration. */
313
- async loadPreset(presetName) {
314
- this.customWeights.loadPreset(presetName);
315
- await this.persistCustomWeights();
316
- }
317
- /** Returns available weight presets. */
318
- listPresets() {
319
- return WEIGHT_PRESETS;
320
- }
321
- /** Returns current custom weight overrides. */
322
- getActiveOverrides() {
323
- return this.customWeights.getOverrides();
324
- }
325
- /** Persist custom weights to encrypted storage. */
326
- async persistCustomWeights() {
327
- if (!this.persistence)
328
- return;
329
- const prefs = await this.persistence.load();
330
- prefs.customWeights = this.customWeights.serialize();
331
- await this.persistence.save(prefs);
332
- this.preferences = prefs;
333
- }
334
- // ── Trajectory multipliers ──────────────────────────────────────────
335
- /**
336
- * Apply trajectory-based multipliers on top of standard emotional overrides.
337
- * Caps all values at 1.0.
338
- */
339
- applyTrajectoryMultipliers(mix, trajectory) {
340
- if (trajectory === 'stable')
341
- return mix;
342
- const result = { ...mix };
343
- const cap = (key, multiplier) => {
344
- result[key] = Math.min(result[key] * multiplier, 1.0);
345
- };
346
- switch (trajectory) {
347
- case 'escalating':
348
- cap('warmth', 1.2);
349
- cap('tacticalEmpathy', 1.2);
350
- cap('stoicCalm', 1.2);
351
- break;
352
- case 'volatile':
353
- cap('warmth', 1.3);
354
- cap('stoicCalm', 1.3);
355
- break;
356
- case 'de_escalating':
357
- // Gently normalize all override-affected traits
358
- for (const key of Object.keys(result)) {
359
- result[key] = Math.min(result[key] * 0.9, 1.0);
360
- }
361
- break;
362
- case 'shifting':
363
- // Slightly dampened to smooth the transition
364
- for (const key of Object.keys(result)) {
365
- result[key] = Math.min(result[key] * 0.8, 1.0);
366
- }
367
- break;
368
- }
369
- return result;
370
- }
371
- // ── Correction learning ──────────────────────────────────────────────
372
- /**
373
- * Records a user correction so the engine can learn from misclassifications.
374
- * Also persists the updated corrections to encrypted storage when available.
375
- */
376
- async recordCorrection(userMessage, detectedDomain, correctedDomain) {
377
- const emotionalRegister = detectContext(userMessage).emotionalRegister;
378
- this.correctionStore.addCorrection({
379
- userMessage,
380
- messageLength: userMessage.length,
381
- detectedDomain,
382
- correctedDomain,
383
- detectedEmotion: emotionalRegister,
384
- });
385
- if (this.persistence) {
386
- await this.persistence.saveCorrections(this.correctionStore);
387
- }
388
- }
389
- /** Load corrections from serialized data (e.g. from encrypted vault). */
390
- loadCorrections(serializedData) {
391
- this.correctionStore = CorrectionStore.deserialize(serializedData);
392
- }
393
- /** Export corrections as a serialized string for encrypted storage. */
394
- exportCorrections() {
395
- return this.correctionStore.serialize();
396
- }
397
- /** Get correction statistics for debugging and transparency. */
398
- getCorrectionStats() {
399
- return this.correctionStore.getStats();
400
- }
401
- // ── Preferences ───────────────────────────────────────────────────────
402
- /** Returns the current preferences. Falls back to in-memory defaults. */
403
- async getPreferences() {
404
- if (this.persistence) {
405
- const prefs = await this.persistence.load();
406
- this.preferences = prefs;
407
- return prefs;
408
- }
409
- // Return a default snapshot when no persistence
410
- return {
411
- corrections: this.correctionStore.serialize(),
412
- customWeights: this.customWeights.serialize(),
413
- showContextIndicator: true,
414
- showSourcesButton: true,
415
- autoDetectContext: true,
416
- defaultContext: null,
417
- contextUsageHistory: {},
418
- totalInteractions: 0,
419
- firstUsed: 0,
420
- lastUsed: 0,
421
- version: 1,
422
- };
423
- }
424
- /** Update a single preference and persist. */
425
- async updatePreference(key, value) {
426
- if (!this.persistence)
427
- return;
428
- const prefs = await this.persistence.load();
429
- prefs[key] = value;
430
- await this.persistence.save(prefs);
431
- this.preferences = prefs;
432
- // Apply side effects
433
- if (key === 'defaultContext') {
434
- this.contextOverride = value;
435
- }
436
- }
437
- /** Clear all persisted data: corrections, preferences, usage history. */
438
- async clearAllData() {
439
- this.correctionStore = new CorrectionStore();
440
- this.contextOverride = null;
441
- this.preferences = undefined;
442
- this.conversationContext.reset();
443
- this.emotionalTracker.reset();
444
- this.customWeights.clear();
445
- if (this.persistence) {
446
- await this.persistence.clearAll();
447
- }
448
- }
449
- // ── Conversation export ────────────────────────────────────────────
450
- /**
451
- * Export a conversation with full personality engine metadata.
452
- * Returns an ExportedConversation that can be serialized to JSON, Markdown, or CSV.
453
- */
454
- exportConversation(messages, conversationId) {
455
- const exporter = new ConversationExporter();
456
- return exporter.export(messages, conversationId);
457
- }
458
- /**
459
- * Export a conversation in the specified format.
460
- * @param format - 'json' | 'markdown' | 'csv'
461
- */
462
- exportConversationAs(messages, conversationId, format) {
463
- const exporter = new ConversationExporter();
464
- const conversation = exporter.export(messages, conversationId);
465
- switch (format) {
466
- case 'json': return exporter.toJSON(conversation);
467
- case 'markdown': return exporter.toMarkdown(conversation);
468
- case 'csv': return exporter.toCSV(conversation);
469
- }
470
- }
471
- /** Export all stored data as JSON string (data portability). */
472
- async exportData() {
473
- if (this.persistence) {
474
- return this.persistence.exportAll();
475
- }
476
- return JSON.stringify(await this.getPreferences(), null, 2);
477
- }
478
- }
479
- // ────────────────────────────────────────────────────────────────────────────
480
- // Convenience factory
481
- // ────────────────────────────────────────────────────────────────────────────
482
- /** Creates a new Architect instance, optionally with encrypted persistence. */
483
- export function createArchitect(storage) {
484
- return new TheArchitect(storage);
485
- }
4
+ // Re-exports everything consumers need from the personality engine.
5
+ // Organized by phase so downstream packages can import from a single path:
6
+ // import { createArchitect, type TraitMix } from '@auxiora/personality/architect';
7
+ // ────────────────────────────────────────────────────────────────────────────
8
+ // Phase 1: core engine
9
+ export { TheArchitect, createArchitect } from './the-architect/index.js';
10
+ export { ARCHITECT_BASE_PROMPT } from './the-architect/system-prompt.js';
11
+ export { CONTEXT_PROFILES } from './the-architect/context-profiles.js';
12
+ export { SOURCE_MAP } from './the-architect/source-map.js';
13
+ export { TRAIT_TO_INSTRUCTION } from './the-architect/trait-to-instruction.js';
14
+ export { detectContext, scoreAllDomains } from './the-architect/context-detector.js';
15
+ export { assemblePromptModifier, getActiveSources } from './the-architect/prompt-assembler.js';
16
+ export { EMOTIONAL_OVERRIDES, applyEmotionalOverride } from './the-architect/emotional-overrides.js';
17
+ // Phase 2: correction learning
18
+ export { CorrectionStore } from './the-architect/correction-store.js';
19
+ // Phase 3: persistence, recommendations, settings
20
+ export { InMemoryEncryptedStorage, VaultStorageAdapter } from './the-architect/persistence-adapter.js';
21
+ export { ArchitectPersistence } from './the-architect/persistence.js';
22
+ export { ContextRecommender } from './the-architect/recommender.js';
23
+ export { ConversationContext } from './the-architect/conversation-context.js';
24
+ export { EmotionalTracker, estimateIntensity } from './the-architect/emotional-tracker.js';
25
+ // Phase 4: custom weights, conversation export
26
+ export { CustomWeights, WEIGHT_PRESETS } from './the-architect/custom-weights.js';
27
+ export { ConversationExporter } from './the-architect/conversation-export.js';
28
+ // Phase 5: self-awareness modules
29
+ export { PreferenceHistory } from './the-architect/preference-history.js';
30
+ export { DecisionLog } from './the-architect/decision-log.js';
31
+ export { FeedbackStore } from './the-architect/feedback-store.js';
32
+ // Phase 5: user model synthesizer
33
+ export { UserModelSynthesizer } from './the-architect/user-model-synthesizer.js';
486
34
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mCAAmC;AACnC,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mCAAmC;AACnC,EAAE;AACF,oEAAoE;AACpE,2EAA2E;AAC3E,qFAAqF;AACrF,+EAA+E;AAE/E,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAYrG,+BAA+B;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGtE,kDAAkD;AAClD,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAEvG,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAG3F,+CAA+C;AAC/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAElF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAG9E,kCAAkC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGlE,kCAAkC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC"}
@@ -6,6 +6,12 @@ export interface ArchitectPreferences {
6
6
  corrections: string;
7
7
  /** Serialized CustomWeights (user trait adjustments). */
8
8
  customWeights?: string;
9
+ /** Serialized PreferenceHistory (timestamped preference changes). */
10
+ preferenceHistory?: string;
11
+ /** Serialized DecisionLog (cross-session decision tracking). */
12
+ decisionLog?: string;
13
+ /** Serialized FeedbackStore (response feedback collection). */
14
+ feedbackStore?: string;
9
15
  /** Whether to show the context indicator pill in the chat UI. */
10
16
  showContextIndicator: boolean;
11
17
  /** Whether to show the sources/provenance button in the chat UI. */
@@ -2,7 +2,7 @@ import { CorrectionStore } from './correction-store.js';
2
2
  // ────────────────────────────────────────────────────────────────────────────
3
3
  // Constants
4
4
  // ────────────────────────────────────────────────────────────────────────────
5
- const CURRENT_VERSION = 1;
5
+ const CURRENT_VERSION = 2;
6
6
  const ALL_DOMAINS = [
7
7
  'security_review', 'code_engineering', 'architecture_design', 'debugging',
8
8
  'team_leadership', 'one_on_one', 'sales_pitch', 'negotiation',
@@ -107,9 +107,16 @@ export class ArchitectPersistence {
107
107
  for (const domain of ALL_DOMAINS) {
108
108
  prefs.contextUsageHistory[domain] ??= 0;
109
109
  }
110
+ prefs.version = 1;
111
+ }
112
+ // Version 1 → 2: add self-awareness modules (preference history, decision log, feedback store)
113
+ if (prefs.version === 1) {
114
+ prefs.preferenceHistory ??= undefined;
115
+ prefs.decisionLog ??= undefined;
116
+ prefs.feedbackStore ??= undefined;
110
117
  prefs.version = CURRENT_VERSION;
111
- await this.save(prefs);
112
118
  }
119
+ await this.save(prefs);
113
120
  return prefs;
114
121
  }
115
122
  }
@@ -0,0 +1,45 @@
1
+ import type { TraitMix, ContextDomain } from '../schema.js';
2
+ export interface PreferenceEntry {
3
+ trait: keyof TraitMix;
4
+ offset: number;
5
+ timestamp: number;
6
+ context: ContextDomain | null;
7
+ source: 'user' | 'preset' | 'feedback';
8
+ reason?: string;
9
+ }
10
+ export interface PreferenceConflict {
11
+ trait: keyof TraitMix;
12
+ entries: PreferenceEntry[];
13
+ resolution: number;
14
+ strategy: 'recency' | 'context';
15
+ }
16
+ export declare class PreferenceHistory {
17
+ private entries;
18
+ private maxEntries;
19
+ /** Record a preference change (called by CustomWeights wrapper). */
20
+ record(entry: Omit<PreferenceEntry, 'timestamp'>): void;
21
+ /**
22
+ * Get the effective offset for a trait, using recency-weighted resolution.
23
+ *
24
+ * 1. If a context-scoped entry exists for the current domain, use it
25
+ * (strategy: 'context').
26
+ * 2. Otherwise, use exponential recency weighting: recent entries count
27
+ * more (decay factor 0.8 per entry) (strategy: 'recency').
28
+ * 3. Entries older than 30 days decay to 10 % weight.
29
+ */
30
+ getEffectiveOffset(trait: keyof TraitMix, currentDomain?: ContextDomain): number;
31
+ /**
32
+ * Detect conflicts: entries for the same trait that pull in opposite
33
+ * directions. Returns conflicts with the resolved value and strategy used.
34
+ */
35
+ detectConflicts(): PreferenceConflict[];
36
+ /** Get history for a specific trait, most recent first. */
37
+ getTraitHistory(trait: keyof TraitMix): PreferenceEntry[];
38
+ /** Serialize for encrypted storage. */
39
+ serialize(): string;
40
+ /** Deserialize from encrypted storage. Validates entry shapes defensively. */
41
+ static deserialize(data: string): PreferenceHistory;
42
+ /** Clear all preference history (user data deletion). */
43
+ clear(): void;
44
+ }
45
+ //# sourceMappingURL=preference-history.d.ts.map