@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
@@ -0,0 +1,100 @@
1
+ import type { ContextDomain } from '../schema.js';
2
+ import type { PreferenceHistory, PreferenceConflict } from './preference-history.js';
3
+ import type { DecisionLog, Decision } from './decision-log.js';
4
+ import type { FeedbackStore } from './feedback-store.js';
5
+ import type { CorrectionStore } from './correction-store.js';
6
+ import type { ArchitectPreferences } from './persistence.js';
7
+ export interface DomainProfile {
8
+ domain: ContextDomain;
9
+ count: number;
10
+ share: number;
11
+ satisfactionRate: number | null;
12
+ feedbackCount: number;
13
+ }
14
+ export interface CommunicationStyle {
15
+ verbosityPreference: number;
16
+ warmthPreference: number;
17
+ humorPreference: number;
18
+ verbosityLabel: 'concise' | 'balanced' | 'detailed';
19
+ toneLabel: 'analytical' | 'balanced' | 'warm';
20
+ }
21
+ export interface SatisfactionProfile {
22
+ overallTrend: 'improving' | 'declining' | 'stable';
23
+ strongDomains: ContextDomain[];
24
+ weakDomains: ContextDomain[];
25
+ totalFeedback: number;
26
+ }
27
+ export interface CorrectionSummary {
28
+ totalCorrections: number;
29
+ topPatterns: Array<{
30
+ from: ContextDomain;
31
+ to: ContextDomain;
32
+ count: number;
33
+ }>;
34
+ }
35
+ export interface UserModel {
36
+ synthesizedAt: number;
37
+ topDomains: DomainProfile[];
38
+ communicationStyle: CommunicationStyle;
39
+ satisfaction: SatisfactionProfile;
40
+ activeDecisions: Decision[];
41
+ dueFollowUps: Decision[];
42
+ preferenceConflicts: PreferenceConflict[];
43
+ correctionSummary: CorrectionSummary;
44
+ totalInteractions: number;
45
+ firstUsed: number;
46
+ lastUsed: number;
47
+ narrative: string;
48
+ }
49
+ interface SynthesizerDeps {
50
+ preferenceHistory: PreferenceHistory;
51
+ decisionLog: DecisionLog;
52
+ feedbackStore: FeedbackStore;
53
+ correctionStore: CorrectionStore;
54
+ preferences?: ArchitectPreferences;
55
+ }
56
+ /**
57
+ * Read-only aggregator that synthesizes a coherent user model from
58
+ * all personality engine data stores. Does not persist its own state.
59
+ *
60
+ * Instantiate fresh and call `synthesize()` to produce a `UserModel`.
61
+ */
62
+ export declare class UserModelSynthesizer {
63
+ private readonly preferenceHistory;
64
+ private readonly decisionLog;
65
+ private readonly feedbackStore;
66
+ private readonly correctionStore;
67
+ private readonly preferences?;
68
+ constructor(deps: SynthesizerDeps);
69
+ /** Synthesize a complete user model. Pure computation, no side effects. */
70
+ synthesize(): UserModel;
71
+ /**
72
+ * Build domain profiles from contextUsageHistory.
73
+ * Returns top 5 non-zero domains sorted by count descending.
74
+ */
75
+ private buildDomainProfiles;
76
+ /**
77
+ * Build communication style from preference history effective offsets.
78
+ * Factors in feedback-suggested adjustments.
79
+ */
80
+ private buildCommunicationStyle;
81
+ /**
82
+ * Build satisfaction profile from feedback store insights.
83
+ * Strong domains: >80% helpful with >=3 feedback entries.
84
+ */
85
+ private buildSatisfactionProfile;
86
+ /**
87
+ * Get active and revisit decisions.
88
+ */
89
+ private getActiveDecisions;
90
+ /**
91
+ * Build correction summary from correction store stats.
92
+ */
93
+ private buildCorrectionSummary;
94
+ /**
95
+ * Generate a deterministic 1-3 sentence narrative describing the user.
96
+ */
97
+ private generateNarrative;
98
+ }
99
+ export {};
100
+ //# sourceMappingURL=user-model-synthesizer.d.ts.map
@@ -0,0 +1,224 @@
1
+ // ────────────────────────────────────────────────────────────────────────────
2
+ // UserModelSynthesizer
3
+ // ────────────────────────────────────────────────────────────────────────────
4
+ /**
5
+ * Read-only aggregator that synthesizes a coherent user model from
6
+ * all personality engine data stores. Does not persist its own state.
7
+ *
8
+ * Instantiate fresh and call `synthesize()` to produce a `UserModel`.
9
+ */
10
+ export class UserModelSynthesizer {
11
+ preferenceHistory;
12
+ decisionLog;
13
+ feedbackStore;
14
+ correctionStore;
15
+ preferences;
16
+ constructor(deps) {
17
+ this.preferenceHistory = deps.preferenceHistory;
18
+ this.decisionLog = deps.decisionLog;
19
+ this.feedbackStore = deps.feedbackStore;
20
+ this.correctionStore = deps.correctionStore;
21
+ this.preferences = deps.preferences;
22
+ }
23
+ /** Synthesize a complete user model. Pure computation, no side effects. */
24
+ synthesize() {
25
+ const topDomains = this.buildDomainProfiles();
26
+ const communicationStyle = this.buildCommunicationStyle();
27
+ const satisfaction = this.buildSatisfactionProfile();
28
+ const activeDecisions = this.getActiveDecisions();
29
+ const dueFollowUps = this.decisionLog.getDueFollowUps();
30
+ const preferenceConflicts = this.preferenceHistory.detectConflicts();
31
+ const correctionSummary = this.buildCorrectionSummary();
32
+ const totalInteractions = this.preferences?.totalInteractions ?? 0;
33
+ const firstUsed = this.preferences?.firstUsed ?? 0;
34
+ const lastUsed = this.preferences?.lastUsed ?? 0;
35
+ const narrative = this.generateNarrative(topDomains, communicationStyle, satisfaction, activeDecisions, totalInteractions);
36
+ return {
37
+ synthesizedAt: Date.now(),
38
+ topDomains,
39
+ communicationStyle,
40
+ satisfaction,
41
+ activeDecisions,
42
+ dueFollowUps,
43
+ preferenceConflicts,
44
+ correctionSummary,
45
+ totalInteractions,
46
+ firstUsed,
47
+ lastUsed,
48
+ narrative,
49
+ };
50
+ }
51
+ // ── Private helpers ─────────────────────────────────────────────────────
52
+ /**
53
+ * Build domain profiles from contextUsageHistory.
54
+ * Returns top 5 non-zero domains sorted by count descending.
55
+ */
56
+ buildDomainProfiles() {
57
+ const usage = this.preferences?.contextUsageHistory;
58
+ if (!usage)
59
+ return [];
60
+ const total = Object.values(usage).reduce((sum, n) => sum + n, 0);
61
+ if (total === 0)
62
+ return [];
63
+ const profiles = [];
64
+ for (const [domain, count] of Object.entries(usage)) {
65
+ if (count === 0)
66
+ continue;
67
+ const feedback = this.feedbackStore.getForDomain(domain);
68
+ const feedbackCount = feedback.length;
69
+ let satisfactionRate = null;
70
+ if (feedbackCount > 0) {
71
+ const helpful = feedback.filter(f => f.rating === 'helpful').length;
72
+ satisfactionRate = helpful / feedbackCount;
73
+ }
74
+ profiles.push({
75
+ domain,
76
+ count,
77
+ share: count / total,
78
+ satisfactionRate,
79
+ feedbackCount,
80
+ });
81
+ }
82
+ // Sort by count descending, take top 5
83
+ profiles.sort((a, b) => b.count - a.count);
84
+ return profiles.slice(0, 5);
85
+ }
86
+ /**
87
+ * Build communication style from preference history effective offsets.
88
+ * Factors in feedback-suggested adjustments.
89
+ */
90
+ buildCommunicationStyle() {
91
+ let verbosityPreference = this.preferenceHistory.getEffectiveOffset('verbosity');
92
+ let warmthPreference = this.preferenceHistory.getEffectiveOffset('warmth');
93
+ const humorPreference = this.preferenceHistory.getEffectiveOffset('humor');
94
+ // Factor in feedback-suggested adjustments
95
+ const insights = this.feedbackStore.getInsights();
96
+ if (insights.suggestedAdjustments.verbosity !== undefined) {
97
+ verbosityPreference += insights.suggestedAdjustments.verbosity;
98
+ }
99
+ if (insights.suggestedAdjustments.warmth !== undefined) {
100
+ warmthPreference += insights.suggestedAdjustments.warmth;
101
+ }
102
+ const verbosityLabel = verbosityPreference < -0.1 ? 'concise' :
103
+ verbosityPreference > 0.1 ? 'detailed' : 'balanced';
104
+ const toneLabel = warmthPreference < -0.1 ? 'analytical' :
105
+ warmthPreference > 0.1 ? 'warm' : 'balanced';
106
+ return {
107
+ verbosityPreference,
108
+ warmthPreference,
109
+ humorPreference,
110
+ verbosityLabel,
111
+ toneLabel,
112
+ };
113
+ }
114
+ /**
115
+ * Build satisfaction profile from feedback store insights.
116
+ * Strong domains: >80% helpful with >=3 feedback entries.
117
+ */
118
+ buildSatisfactionProfile() {
119
+ const insights = this.feedbackStore.getInsights();
120
+ // Compute strong domains: >80% helpful rate with >=3 entries
121
+ const strongDomains = [];
122
+ const usage = this.preferences?.contextUsageHistory;
123
+ if (usage) {
124
+ for (const domain of Object.keys(usage)) {
125
+ const feedback = this.feedbackStore.getForDomain(domain);
126
+ if (feedback.length >= 3) {
127
+ const helpful = feedback.filter(f => f.rating === 'helpful').length;
128
+ if (helpful / feedback.length > 0.8) {
129
+ strongDomains.push(domain);
130
+ }
131
+ }
132
+ }
133
+ }
134
+ return {
135
+ overallTrend: insights.trend,
136
+ strongDomains,
137
+ weakDomains: insights.weakDomains,
138
+ totalFeedback: insights.totalFeedback,
139
+ };
140
+ }
141
+ /**
142
+ * Get active and revisit decisions.
143
+ */
144
+ getActiveDecisions() {
145
+ const active = this.decisionLog.query({ status: 'active', limit: 10 });
146
+ const revisit = this.decisionLog.query({ status: 'revisit', limit: 5 });
147
+ // Merge, deduplicating by id
148
+ const seen = new Set(active.map(d => d.id));
149
+ const merged = [...active];
150
+ for (const d of revisit) {
151
+ if (!seen.has(d.id)) {
152
+ merged.push(d);
153
+ }
154
+ }
155
+ return merged;
156
+ }
157
+ /**
158
+ * Build correction summary from correction store stats.
159
+ */
160
+ buildCorrectionSummary() {
161
+ const stats = this.correctionStore.getStats();
162
+ return {
163
+ totalCorrections: stats.totalCorrections,
164
+ topPatterns: stats.topMisclassifications.slice(0, 3),
165
+ };
166
+ }
167
+ /**
168
+ * Generate a deterministic 1-3 sentence narrative describing the user.
169
+ */
170
+ generateNarrative(topDomains, style, satisfaction, activeDecisions, totalInteractions) {
171
+ const sentences = [];
172
+ // Sentence 1: domain focus
173
+ if (totalInteractions === 0) {
174
+ sentences.push('This is a new user with no interaction history yet.');
175
+ }
176
+ else if (totalInteractions < 5) {
177
+ sentences.push(`This user is just getting started, with ${totalInteractions} interaction${totalInteractions === 1 ? '' : 's'} so far.`);
178
+ }
179
+ else if (topDomains.length === 0) {
180
+ sentences.push(`This user has ${totalInteractions} interactions but no domain usage recorded.`);
181
+ }
182
+ else if (topDomains.length === 1) {
183
+ const d = topDomains[0];
184
+ const pct = Math.round(d.share * 100);
185
+ sentences.push(`This user primarily works in ${formatDomain(d.domain)} (${pct}% of ${totalInteractions} interactions).`);
186
+ }
187
+ else {
188
+ const names = topDomains.slice(0, 3).map(d => formatDomain(d.domain));
189
+ const last = names.pop();
190
+ sentences.push(`Across ${totalInteractions} interactions, this user focuses on ${names.join(', ')} and ${last}.`);
191
+ }
192
+ // Sentence 2: communication style (only if non-balanced)
193
+ if (style.verbosityLabel !== 'balanced' || style.toneLabel !== 'balanced') {
194
+ let styleSentence = 'They prefer ';
195
+ styleSentence += style.verbosityLabel !== 'balanced'
196
+ ? `${style.verbosityLabel} responses`
197
+ : 'responses';
198
+ if (style.toneLabel !== 'balanced') {
199
+ styleSentence += ` with a ${style.toneLabel} tone`;
200
+ }
201
+ styleSentence += '.';
202
+ sentences.push(styleSentence);
203
+ }
204
+ // Sentence 3: satisfaction or activity
205
+ if (satisfaction.overallTrend === 'declining') {
206
+ sentences.push('Recent satisfaction has been declining -- responses may need recalibration.');
207
+ }
208
+ else if (activeDecisions.length > 0) {
209
+ sentences.push(`They have ${activeDecisions.length} active decision thread${activeDecisions.length === 1 ? '' : 's'} being tracked.`);
210
+ }
211
+ else if (satisfaction.overallTrend === 'improving') {
212
+ sentences.push('Satisfaction has been trending upward recently.');
213
+ }
214
+ return sentences.join(' ');
215
+ }
216
+ }
217
+ // ────────────────────────────────────────────────────────────────────────────
218
+ // Helpers
219
+ // ────────────────────────────────────────────────────────────────────────────
220
+ /** Format a domain slug as readable text (e.g. 'code_engineering' → 'code engineering'). */
221
+ function formatDomain(domain) {
222
+ return domain.replace(/_/g, ' ');
223
+ }
224
+ //# sourceMappingURL=user-model-synthesizer.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auxiora/personality",
3
- "version": "1.3.0",
3
+ "version": "1.10.0",
4
4
  "description": "Personality templates and SOUL.md management for Auxiora",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,9 +20,9 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "zod": "^3.23.0",
23
- "@auxiora/core": "1.3.0",
24
- "@auxiora/self-awareness": "1.3.0",
25
- "@auxiora/config": "1.3.0"
23
+ "@auxiora/config": "1.10.0",
24
+ "@auxiora/core": "1.10.0",
25
+ "@auxiora/self-awareness": "1.10.0"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "public"