@auxiora/personality 1.0.0 → 1.3.1
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.
- package/dist/__tests__/architect-awareness-collector.test.d.ts +2 -0
- package/dist/__tests__/architect-awareness-collector.test.d.ts.map +1 -0
- package/dist/__tests__/architect-awareness-collector.test.js +57 -0
- package/dist/__tests__/architect-awareness-collector.test.js.map +1 -0
- package/dist/__tests__/architect-bridge.test.d.ts +2 -0
- package/dist/__tests__/architect-bridge.test.d.ts.map +1 -0
- package/dist/__tests__/architect-bridge.test.js +59 -0
- package/dist/__tests__/architect-bridge.test.js.map +1 -0
- package/dist/__tests__/soul-bias-parser.test.d.ts +2 -0
- package/dist/__tests__/soul-bias-parser.test.d.ts.map +1 -0
- package/dist/__tests__/soul-bias-parser.test.js +47 -0
- package/dist/__tests__/soul-bias-parser.test.js.map +1 -0
- package/dist/architect-awareness-collector.d.ts +20 -0
- package/dist/architect-awareness-collector.d.ts.map +1 -0
- package/dist/architect-awareness-collector.js +41 -0
- package/dist/architect-awareness-collector.js.map +1 -0
- package/dist/architect-bridge.d.ts +35 -0
- package/dist/architect-bridge.d.ts.map +1 -0
- package/dist/architect-bridge.js +70 -0
- package/dist/architect-bridge.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/marketplace/schema.d.ts +6 -6
- package/dist/soul-bias-parser.d.ts +10 -0
- package/dist/soul-bias-parser.d.ts.map +1 -0
- package/dist/soul-bias-parser.js +48 -0
- package/dist/soul-bias-parser.js.map +1 -0
- package/lib/context-detector.d.ts +23 -0
- package/lib/context-detector.js +275 -0
- package/lib/context-profiles.d.ts +3 -0
- package/lib/context-profiles.js +550 -0
- package/lib/conversation-context.d.ts +70 -0
- package/lib/conversation-context.js +144 -0
- package/lib/conversation-export.d.ts +77 -0
- package/lib/conversation-export.js +254 -0
- package/lib/correction-store.d.ts +53 -0
- package/lib/correction-store.js +185 -0
- package/lib/custom-weights.d.ts +49 -0
- package/lib/custom-weights.js +181 -0
- package/lib/decision-log.d.ts +41 -0
- package/lib/decision-log.js +145 -0
- package/lib/emotional-overrides.d.ts +14 -0
- package/lib/emotional-overrides.js +86 -0
- package/lib/emotional-tracker.d.ts +41 -0
- package/lib/emotional-tracker.js +210 -0
- package/lib/feedback-store.d.ts +45 -0
- package/lib/feedback-store.js +152 -0
- package/lib/index.d.ts +204 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +620 -0
- package/lib/index.js.map +1 -0
- package/lib/persistence-adapter.d.ts +55 -0
- package/lib/persistence-adapter.js +50 -0
- package/lib/persistence.d.ts +55 -0
- package/lib/persistence.js +123 -0
- package/lib/preference-history.d.ts +45 -0
- package/lib/preference-history.js +132 -0
- package/lib/prompt-assembler.d.ts +16 -0
- package/lib/prompt-assembler.js +66 -0
- package/lib/recommender.d.ts +25 -0
- package/lib/recommender.js +125 -0
- package/lib/schema.d.ts +177 -0
- package/lib/schema.d.ts.map +1 -0
- package/lib/schema.js +2 -0
- package/lib/schema.js.map +1 -0
- package/lib/source-map.d.ts +9 -0
- package/lib/source-map.js +223 -0
- package/lib/system-prompt.d.ts +2 -0
- package/lib/system-prompt.js +102 -0
- package/lib/the-architect/context-detector.d.ts +23 -0
- package/lib/the-architect/context-detector.d.ts.map +1 -0
- package/lib/the-architect/context-detector.js +275 -0
- package/lib/the-architect/context-detector.js.map +1 -0
- package/lib/the-architect/context-profiles.d.ts +3 -0
- package/lib/the-architect/context-profiles.d.ts.map +1 -0
- package/lib/the-architect/context-profiles.js +550 -0
- package/lib/the-architect/context-profiles.js.map +1 -0
- package/lib/the-architect/conversation-context.d.ts +70 -0
- package/lib/the-architect/conversation-context.js +144 -0
- package/lib/the-architect/conversation-context.js.map +1 -0
- package/lib/the-architect/conversation-export.d.ts +77 -0
- package/lib/the-architect/conversation-export.js +254 -0
- package/lib/the-architect/correction-store.d.ts +53 -0
- package/lib/the-architect/correction-store.d.ts.map +1 -0
- package/lib/the-architect/correction-store.js +185 -0
- package/lib/the-architect/correction-store.js.map +1 -0
- package/lib/the-architect/custom-weights.d.ts +49 -0
- package/lib/the-architect/custom-weights.js +181 -0
- package/lib/the-architect/decision-log.d.ts +41 -0
- package/lib/the-architect/decision-log.d.ts.map +1 -0
- package/lib/the-architect/decision-log.js +145 -0
- package/lib/the-architect/decision-log.js.map +1 -0
- package/lib/the-architect/emotional-overrides.d.ts +14 -0
- package/lib/the-architect/emotional-overrides.d.ts.map +1 -0
- package/lib/the-architect/emotional-overrides.js +86 -0
- package/lib/the-architect/emotional-overrides.js.map +1 -0
- package/lib/the-architect/emotional-tracker.d.ts +41 -0
- package/lib/the-architect/emotional-tracker.js +210 -0
- package/lib/the-architect/feedback-store.d.ts +45 -0
- package/lib/the-architect/feedback-store.d.ts.map +1 -0
- package/lib/the-architect/feedback-store.js +152 -0
- package/lib/the-architect/feedback-store.js.map +1 -0
- package/lib/the-architect/index.d.ts +199 -0
- package/lib/the-architect/index.d.ts.map +1 -0
- package/lib/the-architect/index.js +606 -0
- package/lib/the-architect/index.js.map +1 -0
- package/lib/the-architect/persistence-adapter.d.ts +55 -0
- package/lib/the-architect/persistence-adapter.js +50 -0
- package/lib/the-architect/persistence.d.ts +55 -0
- package/lib/the-architect/persistence.js +123 -0
- package/lib/the-architect/preference-history.d.ts +45 -0
- package/lib/the-architect/preference-history.d.ts.map +1 -0
- package/lib/the-architect/preference-history.js +132 -0
- package/lib/the-architect/preference-history.js.map +1 -0
- package/lib/the-architect/prompt-assembler.d.ts +16 -0
- package/lib/the-architect/prompt-assembler.d.ts.map +1 -0
- package/lib/the-architect/prompt-assembler.js +66 -0
- package/lib/the-architect/prompt-assembler.js.map +1 -0
- package/lib/the-architect/recommender.d.ts +25 -0
- package/lib/the-architect/recommender.js +125 -0
- package/lib/the-architect/source-map.d.ts +9 -0
- package/lib/the-architect/source-map.d.ts.map +1 -0
- package/lib/the-architect/source-map.js +223 -0
- package/lib/the-architect/source-map.js.map +1 -0
- package/lib/the-architect/system-prompt.d.ts +2 -0
- package/lib/the-architect/system-prompt.d.ts.map +1 -0
- package/lib/the-architect/system-prompt.js +102 -0
- package/lib/the-architect/system-prompt.js.map +1 -0
- package/lib/the-architect/trait-to-instruction.d.ts +12 -0
- package/lib/the-architect/trait-to-instruction.d.ts.map +1 -0
- package/lib/the-architect/trait-to-instruction.js +330 -0
- package/lib/the-architect/trait-to-instruction.js.map +1 -0
- package/lib/trait-to-instruction.d.ts +12 -0
- package/lib/trait-to-instruction.js +330 -0
- package/lib/user-model-synthesizer.d.ts +100 -0
- package/lib/user-model-synthesizer.js +224 -0
- package/package.json +15 -3
- package/modes/advisor.md +0 -24
- package/modes/analyst.md +0 -25
- package/modes/companion.md +0 -24
- package/modes/legal.md +0 -1188
- package/modes/operator.md +0 -24
- package/modes/roast.md +0 -24
- package/modes/socratic.md +0 -24
- package/modes/writer.md +0 -23
- package/src/__tests__/builder.test.ts +0 -78
- package/src/__tests__/conversation-builder.test.ts +0 -386
- package/src/__tests__/escalation.test.ts +0 -172
- package/src/__tests__/manager.test.ts +0 -141
- package/src/__tests__/parser.test.ts +0 -101
- package/src/__tests__/security-floor.test.ts +0 -212
- package/src/builder.ts +0 -75
- package/src/conversation-builder.ts +0 -279
- package/src/escalation.ts +0 -162
- package/src/index.ts +0 -55
- package/src/manager.ts +0 -119
- package/src/marketplace/__tests__/scanner.test.ts +0 -159
- package/src/marketplace/__tests__/schema.test.ts +0 -269
- package/src/marketplace/scanner.ts +0 -85
- package/src/marketplace/schema.ts +0 -141
- package/src/modes/__tests__/mode-detector.test.ts +0 -149
- package/src/modes/__tests__/mode-loader.test.ts +0 -143
- package/src/modes/__tests__/prompt-assembler.test.ts +0 -291
- package/src/modes/mode-detector.ts +0 -84
- package/src/modes/mode-loader.ts +0 -105
- package/src/modes/prompt-assembler.ts +0 -278
- package/src/modes/types.ts +0 -67
- package/src/parser.ts +0 -132
- package/src/security-floor.ts +0 -147
- package/src/types.ts +0 -27
- package/src/voice-profiles.ts +0 -88
- package/templates/chill.md +0 -30
- package/templates/creative.md +0 -29
- package/templates/friendly.md +0 -28
- package/templates/mentor.md +0 -31
- package/templates/minimal.md +0 -24
- package/templates/professional.md +0 -28
- package/templates/technical.md +0 -30
- package/tsconfig.json +0 -12
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
2
|
+
// Domain signals
|
|
3
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
const DOMAIN_SIGNALS = {
|
|
5
|
+
security_review: {
|
|
6
|
+
keywords: ['vulnerability', 'vulnerabilities', 'CVE', 'threat', 'exploit', 'patch', 'audit', 'compliance', 'penetration', 'firewall', 'incident', 'breach', 'SIEM', 'SOC', 'CTEM', 'attack surface', 'zero-day', 'Qualys', 'CrowdStrike', 'Splunk', 'Wiz', 'TORQ', 'security', 'encryption', 'authentication', 'authorization', 'password', 'token', 'OAuth', 'RBAC', 'permissions', 'access control', 'hardening', 'malware', 'phishing', 'ransomware', 'hacked', 'hack', 'secure'],
|
|
7
|
+
patterns: ['review this security', 'is this secure', 'how would an attacker', 'what are the risks', 'FCA audit', 'threat model', 'security posture', 'attack vector', 'security review', 'security check', 'pen test', 'red team', 'how safe is', 'lock down', 'tighten security', 'security best practice', 'security issues', 'got hacked', 'been hacked', 'we got hacked', 'check for vulnerabilit'],
|
|
8
|
+
confidence_threshold: 0.35,
|
|
9
|
+
},
|
|
10
|
+
code_engineering: {
|
|
11
|
+
keywords: ['function', 'API', 'deploy', 'refactor', 'test', 'build', 'pipeline', 'CI/CD', 'container', 'microservice', 'endpoint', 'typescript', 'python', 'rust', 'terraform', 'code', 'programming', 'variable', 'database', 'query', 'git', 'commit', 'branch', 'server', 'backend', 'frontend', 'npm', 'docker', 'react', 'node', 'package', 'module', 'class', 'method', 'library', 'framework', 'component', 'repository', 'repo', 'script', 'compiler', 'runtime'],
|
|
12
|
+
patterns: ['write a function', 'debug this', 'optimize this code', 'implement', 'how should I structure', 'write code', 'fix the code', 'add a feature', 'code review', 'pull request', 'write a script', 'build a', 'set up a', 'create an API', 'write a test', 'help me code', 'coding', 'how do I implement'],
|
|
13
|
+
confidence_threshold: 0.35,
|
|
14
|
+
},
|
|
15
|
+
architecture_design: {
|
|
16
|
+
keywords: ['architecture', 'design', 'system', 'scalability', 'ADR', 'microservice', 'monolith', 'event-driven', 'CNAPP', 'platform', 'infrastructure', 'distributed', 'load balancer', 'service mesh', 'database design', 'schema', 'data model', 'tech stack', 'migration', 'modular', 'coupling', 'cohesion', 'abstraction', 'layer'],
|
|
17
|
+
patterns: ['how should we architect', 'what pattern should', 'design decision', 'trade-offs between', 'should we use X or Y', 'system design', 'how should I design', 'what architecture', 'best approach for', 'how to structure', 'high level design', 'technical design'],
|
|
18
|
+
confidence_threshold: 0.35,
|
|
19
|
+
},
|
|
20
|
+
debugging: {
|
|
21
|
+
keywords: ['error', 'bug', 'crash', 'failed', 'broken', 'stack trace', 'exception', 'undefined', 'null', 'timeout', 'fix', 'issue', 'problem', 'wrong', 'unexpected', 'regression', 'flaky', 'intermittent', 'memory leak', 'segfault', 'panic', 'abort', 'logs'],
|
|
22
|
+
patterns: ['why is this', 'not working', 'getting an error', 'keeps failing', 'can you fix', 'what went wrong', "doesn't work", 'help me fix', 'figure out why', 'stopped working', 'something broke', 'track down', 'root cause', "can't figure out", 'keeps crashing', 'throwing an error'],
|
|
23
|
+
confidence_threshold: 0.35,
|
|
24
|
+
},
|
|
25
|
+
team_leadership: {
|
|
26
|
+
keywords: ['team', 'hire', 'hiring', 'performance', 'culture', 'morale', 'feedback', 'promotion', 'development', 'retention', 'onboarding', 'manage', 'leadership', 'report', 'standup', 'org', 'headcount', 'staffing', 'firing', 'letting go', 'PIP', 'underperforming', 'sprint', 'agile', 'people'],
|
|
27
|
+
patterns: ['how do I handle', 'my team is', 'should I tell them', 'managing', 'struggling with their performance', 'lead my team', 'build a team', 'run a team', 'manage my team', 'team meeting', 'team morale', 'team dynamic', 'team culture', 'scale the team', 'hire for', 'fire someone', 'let someone go', 'hire more', 'should I hire', 'grow the team'],
|
|
28
|
+
confidence_threshold: 0.35,
|
|
29
|
+
},
|
|
30
|
+
one_on_one: {
|
|
31
|
+
keywords: ['1:1', 'one-on-one', 'check-in', 'career', 'growth', 'feedback for', 'coaching', 'mentoring', 'direct report', 'skip level', 'performance review'],
|
|
32
|
+
patterns: ['meeting with my', 'how do I give feedback', 'they seem disengaged', 'want to develop them', 'prep for my 1:1', 'give them feedback', 'talk to them about', 'have a conversation with', 'difficult conversation', 'career conversation', 'growth conversation', 'review meeting'],
|
|
33
|
+
confidence_threshold: 0.35,
|
|
34
|
+
},
|
|
35
|
+
sales_pitch: {
|
|
36
|
+
keywords: ['pitch', 'proposal', 'sell', 'demo', 'close', 'deal', 'prospect', 'value prop', 'objection', 'ROI', 'sales', 'revenue', 'pipeline', 'quota', 'lead', 'customer', 'pricing', 'discount', 'upsell', 'renewal'],
|
|
37
|
+
patterns: ['how do I sell', 'convince them to', 'make the case for', 'justify the budget', 'executive presentation', 'close the deal', 'sales pitch', 'sales email', 'sales deck', 'win the deal', 'pitch to', 'sell this to', 'handle objection', 'follow up with the prospect', 'sales call'],
|
|
38
|
+
confidence_threshold: 0.35,
|
|
39
|
+
},
|
|
40
|
+
negotiation: {
|
|
41
|
+
keywords: ['negotiate', 'contract', 'terms', 'concession', 'counter-offer', 'vendor', 'compensation', 'salary', 'offer', 'leverage', 'agreement', 'deal', 'BATNA', 'walkaway', 'raise', 'benefits', 'package'],
|
|
42
|
+
patterns: ['how should I respond to their offer', 'they want us to', 'push back on', 'what leverage do I have', 'negotiate the terms', 'negotiate my', 'ask for a raise', 'counter their offer', 'salary negotiation', 'vendor negotiation', 'contract negotiation', 'negotiate with', 'get a better deal', 'what should I ask for'],
|
|
43
|
+
confidence_threshold: 0.35,
|
|
44
|
+
},
|
|
45
|
+
marketing_content: {
|
|
46
|
+
keywords: ['brand', 'audience', 'campaign', 'SEO', 'content strategy', 'positioning', 'social media', 'newsletter', 'marketing', 'ads', 'advertising', 'funnel', 'conversion', 'engagement', 'branding', 'copy', 'tagline', 'target market', 'launch', 'promotion', 'outreach', 'inbound', 'leads', 'landing page', 'email campaign', 'growth hack'],
|
|
47
|
+
patterns: ['how do we position', 'what should our messaging', 'content calendar', 'build an audience', 'marketing strategy', 'grow our audience', 'write marketing', 'marketing email', 'marketing plan', 'go-to-market', 'product launch', 'brand voice', 'social post', 'ad copy', 'marketing campaign', 'reach more', 'attract customers', 'generate leads', 'promote our'],
|
|
48
|
+
confidence_threshold: 0.35,
|
|
49
|
+
},
|
|
50
|
+
strategic_planning: {
|
|
51
|
+
keywords: ['strategy', 'roadmap', 'vision', 'priority', 'quarter', 'OKR', 'initiative', 'investment', 'resource allocation', 'planning', 'goals', 'objectives', 'KPI', 'metric', 'budget', 'forecast', 'milestone', 'alignment', 'stakeholder'],
|
|
52
|
+
patterns: ['should we invest in', 'what should our strategy be', 'how do we prioritize', 'next quarter', 'three-year plan', 'strategic direction', 'build a roadmap', 'annual plan', 'set goals', 'set OKRs', 'plan for next', 'long-term plan', 'where should we focus', 'resource planning', 'strategic priorities', 'business plan'],
|
|
53
|
+
confidence_threshold: 0.35,
|
|
54
|
+
},
|
|
55
|
+
crisis_management: {
|
|
56
|
+
keywords: ['breach', 'outage', 'incident', 'down', 'emergency', 'compromised', 'escalation', 'P1', 'severity 1', 'urgent', 'critical issue', 'disaster', 'recovery', 'rollback', 'hotfix', 'war room', 'postmortem'],
|
|
57
|
+
patterns: ['we just got', 'everything is broken', 'how do we respond', 'the board is asking', 'media is calling', 'need to act now', 'site is down', 'system is down', 'production is down', 'customers are affected', 'data loss', 'on fire', 'all hands', 'dropped the ball', 'damage control'],
|
|
58
|
+
confidence_threshold: 0.30,
|
|
59
|
+
},
|
|
60
|
+
creative_work: {
|
|
61
|
+
keywords: ['brainstorm', 'idea', 'creative', 'concept', 'innovation', 'vision', 'imagine', 'prototype', 'design thinking', 'inspiration', 'workshop', 'whiteboard', 'explore', 'experiment', 'invent', 'original', 'fresh'],
|
|
62
|
+
patterns: ['help me think of', 'what if we', 'how could we make this more', 'I need ideas for', 'come up with', 'get creative', 'brainstorm ideas', 'think outside the box', 'new ideas for', 'creative ways to', 'how can we innovate', 'reimagine', 'blue sky', 'spitball', 'riff on this', 'help me brainstorm', 'let me brainstorm', 'brainstorm with me'],
|
|
63
|
+
confidence_threshold: 0.35,
|
|
64
|
+
},
|
|
65
|
+
writing_content: {
|
|
66
|
+
keywords: ['blog', 'article', 'post', 'newsletter', 'documentation', 'write', 'draft', 'edit', 'tone', 'copy', 'essay', 'email', 'message', 'announcement', 'memo', 'report', 'summary', 'outline', 'proofread', 'rewrite', 'headline', 'subject line'],
|
|
67
|
+
patterns: ['write a blog post', 'help me draft', 'review this writing', 'how should I frame', 'write an email', 'draft a message', 'write about', 'help me write', 'draft an email', 'write a memo', 'write a report', 'edit this', 'proofread this', 'rewrite this', 'make this sound', 'better way to say', 'rephrase this', 'write a summary', 'craft a message'],
|
|
68
|
+
confidence_threshold: 0.35,
|
|
69
|
+
},
|
|
70
|
+
decision_making: {
|
|
71
|
+
keywords: ['decide', 'choice', 'option', 'trade-off', 'should I', 'pros and cons', 'risk', 'compare', 'alternatives', 'weigh', 'dilemma', 'evaluate', 'assessment', 'criteria', 'or stay', 'or leave', 'or wait'],
|
|
72
|
+
patterns: ['should I do X or Y', 'what would you do', 'help me decide', 'weighing my options', 'which one should I', 'what are my options', 'help me choose', 'which is better', 'A or B', 'make a decision', 'torn between', 'on the fence', 'not sure whether to', 'evaluate my options', 'which path should I', 'take it or', 'stay or go', 'should I take', 'should I accept', 'should I leave', 'should I stay'],
|
|
73
|
+
confidence_threshold: 0.35,
|
|
74
|
+
},
|
|
75
|
+
personal_development: {
|
|
76
|
+
keywords: ['career', 'CISO', 'resume', 'interview', 'skill', 'certification', 'learning', 'growth path', 'mentor', 'promotion', 'promoted', 'job', 'role', 'transition', 'networking', 'LinkedIn', 'portfolio', 'personal brand', 'side project', 'raise', 'title', 'seniority'],
|
|
77
|
+
patterns: ['how do I get to', 'should I pursue', 'what should I learn next', 'preparing for an interview', 'my career path', 'advance my career', 'new role', 'next step in my career', 'get promoted', 'switch careers', 'level up', 'grow as a', 'become a better', 'prepare for', 'break into', 'land a job', 'build my skills', 'take the job', 'new job', 'change jobs', 'stay or leave', 'leave my job'],
|
|
78
|
+
confidence_threshold: 0.35,
|
|
79
|
+
},
|
|
80
|
+
learning_research: {
|
|
81
|
+
keywords: ['explain', 'how does', 'what is', 'teach me', 'understand', 'deep dive', 'research', 'learn', 'tutorial', 'guide', 'concept', 'fundamentals', 'basics', 'primer', 'overview', 'introduction'],
|
|
82
|
+
patterns: ['help me understand', 'explain like', "what's the difference between", 'I want to learn about', 'can you explain', 'how do I learn', 'walk me through', 'break it down', 'ELI5', 'in simple terms', 'how does this work', 'what does this mean', 'tell me about', 'give me an overview', 'crash course', 'quick primer on', 'explain how', 'how does a', 'what are', 'what is a', 'what is the'],
|
|
83
|
+
confidence_threshold: 0.35,
|
|
84
|
+
},
|
|
85
|
+
general: {
|
|
86
|
+
keywords: [],
|
|
87
|
+
patterns: [],
|
|
88
|
+
confidence_threshold: 0,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
92
|
+
// Emotional signals
|
|
93
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
94
|
+
const EMOTIONAL_SIGNALS = {
|
|
95
|
+
stressed: ['overwhelmed', 'drowning', 'too much', "can't keep up", 'burning out', 'exhausted', 'behind on everything', 'swamped'],
|
|
96
|
+
frustrated: ['broken', 'stupid', "doesn't work", 'waste of time', 'tried everything', 'sick of', 'fed up', 'ugh', 'ridiculous'],
|
|
97
|
+
uncertain: ["I don't know", 'not sure', 'confused', 'lost', 'what should I', 'am I wrong', 'is this right', 'no idea'],
|
|
98
|
+
excited: ['amazing', 'breakthrough', 'just realized', 'huge', 'this changes everything', 'figured it out', 'holy', 'incredible'],
|
|
99
|
+
celebratory: ['we did it', 'shipped', 'launched', 'won', 'promoted', 'passed the audit', 'got the offer', 'nailed it'],
|
|
100
|
+
};
|
|
101
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
102
|
+
// Scoring
|
|
103
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
104
|
+
const KEYWORD_WEIGHT = 0.20;
|
|
105
|
+
const PATTERN_WEIGHT = 0.25;
|
|
106
|
+
function scoreDomain(domain, message) {
|
|
107
|
+
const signal = DOMAIN_SIGNALS[domain];
|
|
108
|
+
const lower = message.toLowerCase();
|
|
109
|
+
let score = 0;
|
|
110
|
+
for (const keyword of signal.keywords) {
|
|
111
|
+
if (lower.includes(keyword.toLowerCase())) {
|
|
112
|
+
score += KEYWORD_WEIGHT;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
for (const pattern of signal.patterns) {
|
|
116
|
+
if (lower.includes(pattern.toLowerCase())) {
|
|
117
|
+
score += PATTERN_WEIGHT;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return score;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns all domain scores for debugging and transparency.
|
|
124
|
+
* Useful for understanding why a particular domain was selected.
|
|
125
|
+
*/
|
|
126
|
+
export function scoreAllDomains(message) {
|
|
127
|
+
const scores = {};
|
|
128
|
+
for (const domain of Object.keys(DOMAIN_SIGNALS)) {
|
|
129
|
+
scores[domain] = scoreDomain(domain, message);
|
|
130
|
+
}
|
|
131
|
+
return scores;
|
|
132
|
+
}
|
|
133
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
134
|
+
// Detection logic
|
|
135
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
136
|
+
function detectDomain(message) {
|
|
137
|
+
let bestDomain = 'general';
|
|
138
|
+
let bestScore = 0;
|
|
139
|
+
for (const domain of Object.keys(DOMAIN_SIGNALS)) {
|
|
140
|
+
if (domain === 'general')
|
|
141
|
+
continue;
|
|
142
|
+
const score = scoreDomain(domain, message);
|
|
143
|
+
const threshold = DOMAIN_SIGNALS[domain].confidence_threshold;
|
|
144
|
+
if (score >= threshold && score > bestScore) {
|
|
145
|
+
bestScore = score;
|
|
146
|
+
bestDomain = domain;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { domain: bestDomain, confidence: bestScore };
|
|
150
|
+
}
|
|
151
|
+
function detectEmotionalRegister(message) {
|
|
152
|
+
const lower = message.toLowerCase();
|
|
153
|
+
let bestRegister = 'neutral';
|
|
154
|
+
let bestCount = 0;
|
|
155
|
+
for (const [register, signals] of Object.entries(EMOTIONAL_SIGNALS)) {
|
|
156
|
+
let count = 0;
|
|
157
|
+
for (const signal of signals) {
|
|
158
|
+
if (lower.includes(signal.toLowerCase())) {
|
|
159
|
+
count++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (count > bestCount) {
|
|
163
|
+
bestCount = count;
|
|
164
|
+
bestRegister = register;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Punctuation-based detection as tiebreaker or supplement
|
|
168
|
+
if (bestRegister === 'neutral') {
|
|
169
|
+
const hasExcessiveCaps = (message.replace(/[^A-Z]/g, '').length / Math.max(message.replace(/\s/g, '').length, 1)) > 0.5 && message.length > 10;
|
|
170
|
+
const hasMultipleExclamation = /!{2,}/.test(message);
|
|
171
|
+
const hasEllipsisChains = /\.{3,}/.test(message) || /…{2,}/.test(message);
|
|
172
|
+
if (hasExcessiveCaps && hasMultipleExclamation) {
|
|
173
|
+
// Could be excited or frustrated — check for negative keywords
|
|
174
|
+
const negativeSignals = ['broken', 'stupid', "doesn't work", 'fail', 'wrong', 'terrible', 'awful'];
|
|
175
|
+
const hasNegative = negativeSignals.some((s) => lower.includes(s));
|
|
176
|
+
bestRegister = hasNegative ? 'frustrated' : 'excited';
|
|
177
|
+
}
|
|
178
|
+
else if (hasMultipleExclamation) {
|
|
179
|
+
bestRegister = 'excited';
|
|
180
|
+
}
|
|
181
|
+
else if (hasEllipsisChains) {
|
|
182
|
+
const stressSignals = ['overwhelmed', 'too much', "can't", 'behind'];
|
|
183
|
+
const hasStress = stressSignals.some((s) => lower.includes(s));
|
|
184
|
+
bestRegister = hasStress ? 'stressed' : 'uncertain';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return bestRegister;
|
|
188
|
+
}
|
|
189
|
+
function inferComplexity(message, domain) {
|
|
190
|
+
if (domain === 'crisis_management')
|
|
191
|
+
return 'crisis';
|
|
192
|
+
const wordCount = message.split(/\s+/).length;
|
|
193
|
+
if (wordCount < 20 && /^(what|who|when|where|how|is|are|can|does|do|should)\b/i.test(message.trim())) {
|
|
194
|
+
return 'quick_answer';
|
|
195
|
+
}
|
|
196
|
+
const lower = message.toLowerCase();
|
|
197
|
+
const deepSignals = ['analyze', 'analysis', 'review', 'strategy', 'in-depth', 'deep dive', 'comprehensive', 'evaluate'];
|
|
198
|
+
const hasDeepSignal = deepSignals.some((s) => lower.includes(s));
|
|
199
|
+
if (hasDeepSignal || wordCount > 100)
|
|
200
|
+
return 'deep_analysis';
|
|
201
|
+
return 'moderate';
|
|
202
|
+
}
|
|
203
|
+
function inferStakes(message, domain) {
|
|
204
|
+
if (domain === 'crisis_management')
|
|
205
|
+
return 'critical';
|
|
206
|
+
const lower = message.toLowerCase();
|
|
207
|
+
const criticalSignals = ['board', 'regulator', 'legal', 'FCA', 'SEC', 'lawsuit', 'compliance violation'];
|
|
208
|
+
if (criticalSignals.some((s) => lower.includes(s.toLowerCase())))
|
|
209
|
+
return 'critical';
|
|
210
|
+
const highStakesDomains = ['security_review', 'strategic_planning', 'negotiation'];
|
|
211
|
+
if (highStakesDomains.includes(domain))
|
|
212
|
+
return 'high';
|
|
213
|
+
if (domain === 'decision_making' && lower.includes('irreversible'))
|
|
214
|
+
return 'high';
|
|
215
|
+
const lowStakesDomains = ['learning_research', 'general'];
|
|
216
|
+
if (lowStakesDomains.includes(domain))
|
|
217
|
+
return 'low';
|
|
218
|
+
return 'moderate';
|
|
219
|
+
}
|
|
220
|
+
function inferMode(message, _history) {
|
|
221
|
+
const lower = message.toLowerCase();
|
|
222
|
+
const teamSignals = ['team', 'we ', 'our ', 'colleague', 'direct report', 'my report', 'my manager', 'my lead'];
|
|
223
|
+
if (teamSignals.some((s) => lower.includes(s)))
|
|
224
|
+
return 'team_context';
|
|
225
|
+
const externalSignals = ['customer', 'prospect', 'vendor', 'client', 'public', 'board', 'investor', 'media', 'audience'];
|
|
226
|
+
if (externalSignals.some((s) => lower.includes(s)))
|
|
227
|
+
return 'external_facing';
|
|
228
|
+
const personalSignals = ['my career', 'my growth', 'I feel', "I'm struggling", 'personal', 'my goals', 'my path'];
|
|
229
|
+
if (personalSignals.some((s) => lower.includes(s)))
|
|
230
|
+
return 'personal';
|
|
231
|
+
return 'solo_work';
|
|
232
|
+
}
|
|
233
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
234
|
+
// Public API
|
|
235
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
236
|
+
/**
|
|
237
|
+
* Detects the full task context from a user message and optional conversation
|
|
238
|
+
* history. Combines domain detection, emotional register analysis, complexity
|
|
239
|
+
* inference, stakes assessment, and mode classification into a single
|
|
240
|
+
* TaskContext object that drives trait modulation.
|
|
241
|
+
*
|
|
242
|
+
* When a `correctionStore` is provided, the auto-detected domain is checked
|
|
243
|
+
* against learned correction patterns. If a high-confidence correction is
|
|
244
|
+
* found, it overrides the detection and the `corrected` / `originalDomain`
|
|
245
|
+
* fields are set on the returned context.
|
|
246
|
+
*/
|
|
247
|
+
export function detectContext(userMessage, history, correctionStore) {
|
|
248
|
+
const { domain: detectedDomain, confidence } = detectDomain(userMessage);
|
|
249
|
+
const emotionalRegister = detectEmotionalRegister(userMessage);
|
|
250
|
+
// Check for learned corrections
|
|
251
|
+
let domain = detectedDomain;
|
|
252
|
+
let corrected = false;
|
|
253
|
+
let originalDomain;
|
|
254
|
+
if (correctionStore) {
|
|
255
|
+
const suggestion = correctionStore.suggestCorrection(userMessage, detectedDomain);
|
|
256
|
+
if (suggestion !== null) {
|
|
257
|
+
originalDomain = detectedDomain;
|
|
258
|
+
domain = suggestion;
|
|
259
|
+
corrected = true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const complexity = inferComplexity(userMessage, domain);
|
|
263
|
+
const stakes = inferStakes(userMessage, domain);
|
|
264
|
+
const mode = inferMode(userMessage, history);
|
|
265
|
+
return {
|
|
266
|
+
domain,
|
|
267
|
+
emotionalRegister,
|
|
268
|
+
complexity,
|
|
269
|
+
stakes,
|
|
270
|
+
mode,
|
|
271
|
+
...(corrected ? { corrected, originalDomain } : {}),
|
|
272
|
+
detectionConfidence: confidence,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=context-detector.js.map
|