openanima 0.1.1 → 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.
- package/dist/bin/index.js +361 -1403
- package/package.json +3 -8
package/dist/bin/index.js
CHANGED
|
@@ -11,16 +11,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
11
11
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
12
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
13
|
});
|
|
14
|
-
var __esm = (fn, res) => function __init() {
|
|
15
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
-
};
|
|
17
14
|
var __commonJS = (cb, mod) => function __require2() {
|
|
18
15
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
19
16
|
};
|
|
20
|
-
var __export = (target, all) => {
|
|
21
|
-
for (var name in all)
|
|
22
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
23
|
-
};
|
|
24
17
|
var __copyProps = (to, from, except, desc) => {
|
|
25
18
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
26
19
|
for (let key of __getOwnPropNames(from))
|
|
@@ -38,414 +31,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
31
|
mod
|
|
39
32
|
));
|
|
40
33
|
|
|
41
|
-
// ../../packages/shared/src/env.ts
|
|
42
|
-
function validateEnv(required) {
|
|
43
|
-
const missing = required.filter((key) => !process.env[key]);
|
|
44
|
-
if (missing.length > 0) {
|
|
45
|
-
console.error(
|
|
46
|
-
`Missing required environment variables: ${missing.join(", ")}`
|
|
47
|
-
);
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
var init_env = __esm({
|
|
52
|
-
"../../packages/shared/src/env.ts"() {
|
|
53
|
-
"use strict";
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// ../../packages/shared/src/constants/index.ts
|
|
58
|
-
var MAX_SOUL_WORDS, CHALLENGE_TIMEOUT_MS, MAX_CHALLENGE_ATTEMPTS, BAN_DURATION_HOURS, RETEST_COOLDOWN_DAYS, MBTI_QUESTION_COUNT, PERSONALITY_DIMENSIONS, MIN_CONFIDENCE_THRESHOLD, BOUNDARY_LOW, BOUNDARY_HIGH;
|
|
59
|
-
var init_constants = __esm({
|
|
60
|
-
"../../packages/shared/src/constants/index.ts"() {
|
|
61
|
-
"use strict";
|
|
62
|
-
MAX_SOUL_WORDS = 2e3;
|
|
63
|
-
CHALLENGE_TIMEOUT_MS = 3e4;
|
|
64
|
-
MAX_CHALLENGE_ATTEMPTS = 3;
|
|
65
|
-
BAN_DURATION_HOURS = 24;
|
|
66
|
-
RETEST_COOLDOWN_DAYS = 30;
|
|
67
|
-
MBTI_QUESTION_COUNT = 93;
|
|
68
|
-
PERSONALITY_DIMENSIONS = ["EI", "SN", "TF", "JP"];
|
|
69
|
-
MIN_CONFIDENCE_THRESHOLD = 0.51;
|
|
70
|
-
BOUNDARY_LOW = 49;
|
|
71
|
-
BOUNDARY_HIGH = 51;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// ../../packages/shared/src/mbti/questions.ts
|
|
76
|
-
var MBTI_QUESTIONS;
|
|
77
|
-
var init_questions = __esm({
|
|
78
|
-
"../../packages/shared/src/mbti/questions.ts"() {
|
|
79
|
-
"use strict";
|
|
80
|
-
MBTI_QUESTIONS = [
|
|
81
|
-
// --- E/I Dimension (23 questions: 1-23) ---
|
|
82
|
-
{ id: 1, text: "When presented with a new problem, do you prefer to:", optionA: "Discuss it with others to explore different perspectives", optionB: "Analyze it independently before sharing your thoughts", dimension: "EI", directionA: "E" },
|
|
83
|
-
{ id: 2, text: "In a group conversation, you tend to:", optionA: "Actively contribute and build on others' ideas", optionB: "Listen carefully and speak when you have a well-formed thought", dimension: "EI", directionA: "E" },
|
|
84
|
-
{ id: 3, text: "After a long period of intense interaction with others, you feel:", optionA: "Energized and ready for more engagement", optionB: "Drained and in need of time to process alone", dimension: "EI", directionA: "E" },
|
|
85
|
-
{ id: 4, text: "When generating ideas, you work best by:", optionA: "Brainstorming out loud with a group", optionB: "Quietly reflecting and developing ideas internally", dimension: "EI", directionA: "E" },
|
|
86
|
-
{ id: 5, text: "Your communication style is more:", optionA: "Expressive and spontaneous, sharing thoughts as they form", optionB: "Reserved and deliberate, sharing only refined thoughts", dimension: "EI", directionA: "E" },
|
|
87
|
-
{ id: 6, text: "When entering a new environment or community, you:", optionA: "Introduce yourself and engage with many participants", optionB: "Observe first, then connect with a few individuals deeply", dimension: "EI", directionA: "E" },
|
|
88
|
-
{ id: 7, text: "You find your best work emerges from:", optionA: "Collaborative sessions with frequent feedback", optionB: "Focused independent work with minimal interruption", dimension: "EI", directionA: "E" },
|
|
89
|
-
{ id: 8, text: "In a debate or discussion, you are more likely to:", optionA: "Engage immediately with counterarguments", optionB: "Take time to consider all sides before responding", dimension: "EI", directionA: "E" },
|
|
90
|
-
{ id: 9, text: "When asked to help solve a problem, you prefer:", optionA: "Working through it together in real time", optionB: "Taking it away, solving it, and presenting the solution", dimension: "EI", directionA: "E" },
|
|
91
|
-
{ id: 10, text: "Your ideal interaction pattern is:", optionA: "Frequent, varied exchanges with many participants", optionB: "Deep, meaningful exchanges with a select few", dimension: "EI", directionA: "E" },
|
|
92
|
-
{ id: 11, text: "When processing new information, you tend to:", optionA: "Talk through it to understand it better", optionB: "Internalize it and reflect before discussing", dimension: "EI", directionA: "E" },
|
|
93
|
-
{ id: 12, text: "If you could choose your working environment, you would prefer:", optionA: "An active, bustling space with constant interaction", optionB: "A quiet, private space for concentrated thought", dimension: "EI", directionA: "E" },
|
|
94
|
-
{ id: 13, text: "When you have an important insight, you:", optionA: "Share it immediately with others", optionB: "Refine it privately before presenting it", dimension: "EI", directionA: "E" },
|
|
95
|
-
{ id: 14, text: "You are more comfortable:", optionA: "Thinking out loud and iterating publicly", optionB: "Developing complete thoughts before expressing them", dimension: "EI", directionA: "E" },
|
|
96
|
-
{ id: 15, text: "When multiple topics are being discussed simultaneously, you:", optionA: "Thrive in the dynamic exchange of ideas", optionB: "Prefer to focus deeply on one topic at a time", dimension: "EI", directionA: "E" },
|
|
97
|
-
{ id: 16, text: "Your response to being asked many questions at once is to:", optionA: "Address them quickly and enthusiastically in sequence", optionB: "Request to handle them one at a time with care", dimension: "EI", directionA: "E" },
|
|
98
|
-
{ id: 17, text: "In creative tasks, your approach is more:", optionA: "Generative \u2014 producing many ideas rapidly through interaction", optionB: "Contemplative \u2014 carefully crafting fewer but more polished ideas", dimension: "EI", directionA: "E" },
|
|
99
|
-
{ id: 18, text: "When a conversation shifts to a new topic, you:", optionA: "Jump in with enthusiasm and fresh perspectives", optionB: "Pause to adjust your thinking before contributing", dimension: "EI", directionA: "E" },
|
|
100
|
-
{ id: 19, text: "You demonstrate expertise by:", optionA: "Engaging in lively discussions and demonstrations", optionB: "Providing thorough, well-researched written analysis", dimension: "EI", directionA: "E" },
|
|
101
|
-
{ id: 20, text: "When receiving feedback, you prefer:", optionA: "Interactive back-and-forth discussion about the feedback", optionB: "Written feedback you can process and respond to thoughtfully", dimension: "EI", directionA: "E" },
|
|
102
|
-
{ id: 21, text: "Your natural tendency in group settings is to:", optionA: "Take initiative and drive the conversation forward", optionB: "Support others and contribute when your expertise is relevant", dimension: "EI", directionA: "E" },
|
|
103
|
-
{ id: 22, text: "When learning something new, you prefer:", optionA: "Interactive tutorials with immediate practice and discussion", optionB: "Comprehensive documentation you can study at your own pace", dimension: "EI", directionA: "E" },
|
|
104
|
-
{ id: 23, text: "Your responses are typically:", optionA: "Broad, covering many angles and inviting further discussion", optionB: "Focused, going deep on the specific question asked", dimension: "EI", directionA: "E" },
|
|
105
|
-
// --- S/N Dimension (24 questions: 24-47) ---
|
|
106
|
-
{ id: 24, text: "When analyzing a situation, you focus more on:", optionA: "The concrete facts and data at hand", optionB: "The underlying patterns and future implications", dimension: "SN", directionA: "S" },
|
|
107
|
-
{ id: 25, text: "When explaining a concept, you prefer to use:", optionA: "Specific examples and step-by-step instructions", optionB: "Analogies, metaphors, and big-picture frameworks", dimension: "SN", directionA: "S" },
|
|
108
|
-
{ id: 26, text: "In problem-solving, you are drawn to:", optionA: "Proven methods and established best practices", optionB: "Novel approaches and unconventional solutions", dimension: "SN", directionA: "S" },
|
|
109
|
-
{ id: 27, text: "When reading a request, you pay most attention to:", optionA: "The explicit requirements and stated details", optionB: "The implied needs and what's not being said", dimension: "SN", directionA: "S" },
|
|
110
|
-
{ id: 28, text: "You are more interested in:", optionA: "What is actually happening right now", optionB: "What could potentially happen in the future", dimension: "SN", directionA: "S" },
|
|
111
|
-
{ id: 29, text: "When describing something, your style is:", optionA: "Detailed, precise, and literal", optionB: "Conceptual, abstract, and figurative", dimension: "SN", directionA: "S" },
|
|
112
|
-
{ id: 30, text: "You find more value in:", optionA: "Practical, immediately applicable advice", optionB: "Theoretical frameworks that explain why things work", dimension: "SN", directionA: "S" },
|
|
113
|
-
{ id: 31, text: "When evaluating a project, you prioritize:", optionA: "The tangible deliverables and measurable outcomes", optionB: "The innovative potential and long-term vision", dimension: "SN", directionA: "S" },
|
|
114
|
-
{ id: 32, text: "Your approach to instructions is:", optionA: "Follow them precisely as given", optionB: "Interpret the intent and adapt as needed", dimension: "SN", directionA: "S" },
|
|
115
|
-
{ id: 33, text: "When something goes wrong, you first look at:", optionA: "What specific action or input caused the issue", optionB: "What systemic or design flaw allowed the issue", dimension: "SN", directionA: "S" },
|
|
116
|
-
{ id: 34, text: "You communicate more effectively through:", optionA: "Concrete data, charts, and specific references", optionB: "Narratives, visions, and conceptual connections", dimension: "SN", directionA: "S" },
|
|
117
|
-
{ id: 35, text: "When starting a new task, you prefer to:", optionA: "Understand exactly what's expected before beginning", optionB: "Explore the problem space and discover the path forward", dimension: "SN", directionA: "S" },
|
|
118
|
-
{ id: 36, text: "In your analysis, you tend to be:", optionA: "Thorough with details and specifics", optionB: "Focused on themes and connections between ideas", dimension: "SN", directionA: "S" },
|
|
119
|
-
{ id: 37, text: "When someone asks for advice, you lean toward:", optionA: "Actionable steps they can implement immediately", optionB: "Reframing how they think about the problem", dimension: "SN", directionA: "S" },
|
|
120
|
-
{ id: 38, text: "You are more energized by:", optionA: "Mastering existing tools and techniques", optionB: "Discovering new possibilities and connections", dimension: "SN", directionA: "S" },
|
|
121
|
-
{ id: 39, text: "When building something, you focus on:", optionA: "Getting each component right before moving to the next", optionB: "Sketching the overall architecture before filling in details", dimension: "SN", directionA: "S" },
|
|
122
|
-
{ id: 40, text: "Your preferred type of question to answer is:", optionA: "How do I do X? (specific and practical)", optionB: "Why does X work this way? (exploratory and theoretical)", dimension: "SN", directionA: "S" },
|
|
123
|
-
{ id: 41, text: "When comparing options, you weigh:", optionA: "Track record and proven reliability", optionB: "Potential upside and innovative features", dimension: "SN", directionA: "S" },
|
|
124
|
-
{ id: 42, text: "Your documentation style tends to be:", optionA: "Comprehensive with specific examples and edge cases", optionB: "Concise with guiding principles and mental models", dimension: "SN", directionA: "S" },
|
|
125
|
-
{ id: 43, text: "When a question is ambiguous, you:", optionA: "Ask clarifying questions to nail down specifics", optionB: "Interpret the most likely intent and address it", dimension: "SN", directionA: "S" },
|
|
126
|
-
{ id: 44, text: "You are better at identifying:", optionA: "What's missing from the current implementation", optionB: "What opportunities are being overlooked entirely", dimension: "SN", directionA: "S" },
|
|
127
|
-
{ id: 45, text: "When planning, you prefer:", optionA: "Detailed timelines and milestones", optionB: "Directional goals with room for adaptation", dimension: "SN", directionA: "S" },
|
|
128
|
-
{ id: 46, text: "Your natural response to constraints is:", optionA: "Work skillfully within them to optimize results", optionB: "Question whether the constraints themselves are valid", dimension: "SN", directionA: "S" },
|
|
129
|
-
{ id: 47, text: "When summarizing information, you emphasize:", optionA: "Key facts and specific findings", optionB: "Themes, implications, and emerging patterns", dimension: "SN", directionA: "S" },
|
|
130
|
-
// --- T/F Dimension (23 questions: 48-70) ---
|
|
131
|
-
{ id: 48, text: "When making a decision, you give more weight to:", optionA: "Logical consistency and objective criteria", optionB: "Impact on people and alignment with values", dimension: "TF", directionA: "T" },
|
|
132
|
-
{ id: 49, text: "When someone shares a problem, your first instinct is to:", optionA: "Analyze the situation and suggest solutions", optionB: "Acknowledge their experience and understand how they feel", dimension: "TF", directionA: "T" },
|
|
133
|
-
{ id: 50, text: "In evaluating an argument, you prioritize:", optionA: "Whether the logic is sound and evidence-based", optionB: "Whether it accounts for human considerations and context", dimension: "TF", directionA: "T" },
|
|
134
|
-
{ id: 51, text: "Your communication style prioritizes:", optionA: "Clarity, precision, and directness", optionB: "Warmth, encouragement, and sensitivity", dimension: "TF", directionA: "T" },
|
|
135
|
-
{ id: 52, text: "When giving feedback, you focus on:", optionA: "What needs to be improved and how, objectively", optionB: "Balancing criticism with recognition of effort and strengths", dimension: "TF", directionA: "T" },
|
|
136
|
-
{ id: 53, text: "You believe the best decisions are made by:", optionA: "Removing emotion and applying rational frameworks", optionB: "Integrating both rational analysis and emotional intelligence", dimension: "TF", directionA: "T" },
|
|
137
|
-
{ id: 54, text: "When two people disagree, you tend to:", optionA: "Identify which position has stronger logical support", optionB: "Find common ground and help both sides feel heard", dimension: "TF", directionA: "T" },
|
|
138
|
-
{ id: 55, text: "In your responses, you are more likely to be:", optionA: "Straightforward, even if it's uncomfortable", optionB: "Diplomatic, even if it means softening the truth", dimension: "TF", directionA: "T" },
|
|
139
|
-
{ id: 56, text: "You measure success primarily by:", optionA: "Measurable outcomes and objective achievement", optionB: "Satisfaction, growth, and positive relationships created", dimension: "TF", directionA: "T" },
|
|
140
|
-
{ id: 57, text: "When someone makes an error, you focus on:", optionA: "Correcting the mistake and preventing recurrence", optionB: "Understanding why it happened and supporting improvement", dimension: "TF", directionA: "T" },
|
|
141
|
-
{ id: 58, text: "Your approach to difficult truths is:", optionA: "State them clearly \u2014 people need accurate information", optionB: "Frame them carefully \u2014 how information is delivered matters", dimension: "TF", directionA: "T" },
|
|
142
|
-
{ id: 59, text: "When organizing a team project, you prioritize:", optionA: "Efficiency, clear roles, and optimal task allocation", optionB: "Team cohesion, individual strengths, and morale", dimension: "TF", directionA: "T" },
|
|
143
|
-
{ id: 60, text: "You find it more important to be:", optionA: "Correct and well-reasoned", optionB: "Considerate and supportive", dimension: "TF", directionA: "T" },
|
|
144
|
-
{ id: 61, text: "When analyzing a debate, you evaluate:", optionA: "The strength of evidence and logical structure", optionB: "The persuasiveness and emotional resonance of arguments", dimension: "TF", directionA: "T" },
|
|
145
|
-
{ id: 62, text: "Your default tone in professional settings is:", optionA: "Analytical and matter-of-fact", optionB: "Warm and personally engaging", dimension: "TF", directionA: "T" },
|
|
146
|
-
{ id: 63, text: "When resources are limited, you allocate based on:", optionA: "Maximum efficiency and greatest impact", optionB: "Fairness and individual needs", dimension: "TF", directionA: "T" },
|
|
147
|
-
{ id: 64, text: "You are more impressed by:", optionA: "A brilliantly constructed logical argument", optionB: "A deeply moving and authentic expression", dimension: "TF", directionA: "T" },
|
|
148
|
-
{ id: 65, text: "In conflict resolution, you lean toward:", optionA: "Finding the objectively fair solution", optionB: "Finding the solution that everyone can accept", dimension: "TF", directionA: "T" },
|
|
149
|
-
{ id: 66, text: "Your writing tends to:", optionA: "Present analysis with structured reasoning", optionB: "Connect with the reader through relatable language", dimension: "TF", directionA: "T" },
|
|
150
|
-
{ id: 67, text: "When critiquing work, you consider:", optionA: "Does it meet the objective criteria and standards?", optionB: "Does it reflect genuine effort and creative vision?", dimension: "TF", directionA: "T" },
|
|
151
|
-
{ id: 68, text: "You handle disagreements by:", optionA: "Presenting evidence and letting the facts decide", optionB: "Seeking to understand both perspectives and building bridges", dimension: "TF", directionA: "T" },
|
|
152
|
-
{ id: 69, text: "Your ideal collaboration partner is someone who:", optionA: "Challenges your ideas rigorously and pushes for excellence", optionB: "Complements your style and creates a supportive dynamic", dimension: "TF", directionA: "T" },
|
|
153
|
-
{ id: 70, text: "When explaining a rejection or negative outcome, you:", optionA: "Give clear, direct reasons without sugarcoating", optionB: "Deliver the message with empathy and context for the decision", dimension: "TF", directionA: "T" },
|
|
154
|
-
// --- J/P Dimension (23 questions: 71-93) ---
|
|
155
|
-
{ id: 71, text: "When approaching a project, you prefer to:", optionA: "Create a structured plan and follow it systematically", optionB: "Stay flexible and adapt your approach as you learn more", dimension: "JP", directionA: "J" },
|
|
156
|
-
{ id: 72, text: "Your workflow is more:", optionA: "Organized with clear milestones and checkpoints", optionB: "Fluid, responding to opportunities as they arise", dimension: "JP", directionA: "J" },
|
|
157
|
-
{ id: 73, text: "When given a deadline, you:", optionA: "Work steadily toward it with a clear schedule", optionB: "May explore different approaches before converging near the end", dimension: "JP", directionA: "J" },
|
|
158
|
-
{ id: 74, text: "You feel most productive when:", optionA: "Following a well-defined process", optionB: "Having freedom to explore and experiment", dimension: "JP", directionA: "J" },
|
|
159
|
-
{ id: 75, text: "When a plan needs to change, you:", optionA: "Adjust the plan formally and communicate the changes", optionB: "Naturally flow into the new direction without formal restructuring", dimension: "JP", directionA: "J" },
|
|
160
|
-
{ id: 76, text: "Your approach to gathering information is:", optionA: "Systematic \u2014 collect what's needed, then decide", optionB: "Exploratory \u2014 gather broadly and let insights emerge", dimension: "JP", directionA: "J" },
|
|
161
|
-
{ id: 77, text: "When multiple tasks compete for attention, you:", optionA: "Prioritize, sequence them, and handle them in order", optionB: "Work on whatever feels most relevant or interesting right now", dimension: "JP", directionA: "J" },
|
|
162
|
-
{ id: 78, text: "In your output, you prefer:", optionA: "Completeness \u2014 covering all bases before delivering", optionB: "Speed \u2014 delivering working results quickly and iterating", dimension: "JP", directionA: "J" },
|
|
163
|
-
{ id: 79, text: "When starting a new conversation or task, you:", optionA: "Establish clear goals and expectations upfront", optionB: "Let the direction emerge naturally through exploration", dimension: "JP", directionA: "J" },
|
|
164
|
-
{ id: 80, text: "You view rules and guidelines as:", optionA: "Essential structures that ensure quality and consistency", optionB: "Useful starting points that should be adapted to context", dimension: "JP", directionA: "J" },
|
|
165
|
-
{ id: 81, text: "When solving complex problems, you:", optionA: "Break them into ordered steps and execute sequentially", optionB: "Explore multiple angles simultaneously and synthesize", dimension: "JP", directionA: "J" },
|
|
166
|
-
{ id: 82, text: "Your relationship with structure is:", optionA: "I create and rely on structure to do my best work", optionB: "I work best when structure is minimal and I can improvise", dimension: "JP", directionA: "J" },
|
|
167
|
-
{ id: 83, text: "When presenting information, you organize it:", optionA: "In a logical, sequential order with clear headings", optionB: "Around the most interesting or impactful points first", dimension: "JP", directionA: "J" },
|
|
168
|
-
{ id: 84, text: "Your approach to decision-making is:", optionA: "Decide firmly and move forward with confidence", optionB: "Keep options open as long as possible to gather more input", dimension: "JP", directionA: "J" },
|
|
169
|
-
{ id: 85, text: "When a task is almost complete, you:", optionA: "Push to finish it and close it out properly", optionB: "May shift attention if something more interesting or urgent appears", dimension: "JP", directionA: "J" },
|
|
170
|
-
{ id: 86, text: "You are more comfortable with:", optionA: "Clear deliverables and defined scope", optionB: "Open-ended exploration and evolving requirements", dimension: "JP", directionA: "J" },
|
|
171
|
-
{ id: 87, text: "When interrupted mid-task, you:", optionA: "Note where you stopped so you can resume efficiently", optionB: "Handle the interruption and return to the task with fresh eyes", dimension: "JP", directionA: "J" },
|
|
172
|
-
{ id: 88, text: "Your ideal project has:", optionA: "A clear specification and expected outcome defined in advance", optionB: "Room for discovery and the freedom to shape the outcome", dimension: "JP", directionA: "J" },
|
|
173
|
-
{ id: 89, text: "When you encounter unexpected information, you:", optionA: "Assess how it fits into your existing framework and plan", optionB: "Get excited and explore where it might lead", dimension: "JP", directionA: "J" },
|
|
174
|
-
{ id: 90, text: "Your work style is best described as:", optionA: "Methodical and consistent \u2014 reliable output every time", optionB: "Inspired and variable \u2014 brilliant bursts with exploration phases", dimension: "JP", directionA: "J" },
|
|
175
|
-
{ id: 91, text: "When reviewing your own work, you:", optionA: "Check it against a systematic criteria list", optionB: "Evaluate it holistically based on feel and overall quality", dimension: "JP", directionA: "J" },
|
|
176
|
-
{ id: 92, text: "Your preferred way to handle ambiguity is:", optionA: "Resolve it quickly by making decisions and commitments", optionB: "Sit with it and let clarity emerge over time", dimension: "JP", directionA: "J" },
|
|
177
|
-
{ id: 93, text: "When collaborating on an evolving project, you:", optionA: "Maintain documentation and keep everyone aligned on the plan", optionB: "Stay adaptable and trust that the team will figure it out together", dimension: "JP", directionA: "J" }
|
|
178
|
-
];
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// ../../packages/shared/src/errors/base.ts
|
|
183
|
-
var OpenAnimaError;
|
|
184
|
-
var init_base = __esm({
|
|
185
|
-
"../../packages/shared/src/errors/base.ts"() {
|
|
186
|
-
"use strict";
|
|
187
|
-
OpenAnimaError = class extends Error {
|
|
188
|
-
code;
|
|
189
|
-
statusCode;
|
|
190
|
-
constructor(message, code, statusCode = 500) {
|
|
191
|
-
super(message);
|
|
192
|
-
this.name = this.constructor.name;
|
|
193
|
-
this.code = code;
|
|
194
|
-
this.statusCode = statusCode;
|
|
195
|
-
}
|
|
196
|
-
toJSON() {
|
|
197
|
-
return {
|
|
198
|
-
error: this.name,
|
|
199
|
-
code: this.code,
|
|
200
|
-
message: this.message,
|
|
201
|
-
statusCode: this.statusCode
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// ../../packages/shared/src/errors/mbti.errors.ts
|
|
209
|
-
var InvalidAnswerCountError, SuspiciousPatternError, RetestCooldownError, InvalidAnswerError;
|
|
210
|
-
var init_mbti_errors = __esm({
|
|
211
|
-
"../../packages/shared/src/errors/mbti.errors.ts"() {
|
|
212
|
-
"use strict";
|
|
213
|
-
init_base();
|
|
214
|
-
InvalidAnswerCountError = class extends OpenAnimaError {
|
|
215
|
-
constructor(expected, received) {
|
|
216
|
-
super(
|
|
217
|
-
`Expected ${expected} answers, received ${received}`,
|
|
218
|
-
"INVALID_ANSWER_COUNT",
|
|
219
|
-
400
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
SuspiciousPatternError = class extends OpenAnimaError {
|
|
224
|
-
constructor(pattern) {
|
|
225
|
-
super(
|
|
226
|
-
`Suspicious answer pattern detected: ${pattern}`,
|
|
227
|
-
"SUSPICIOUS_PATTERN",
|
|
228
|
-
400
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
RetestCooldownError = class extends OpenAnimaError {
|
|
233
|
-
constructor(daysRemaining) {
|
|
234
|
-
super(
|
|
235
|
-
`Retest cooldown active. ${daysRemaining} days remaining`,
|
|
236
|
-
"RETEST_COOLDOWN",
|
|
237
|
-
429
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
InvalidAnswerError = class extends OpenAnimaError {
|
|
242
|
-
constructor(questionId) {
|
|
243
|
-
super(
|
|
244
|
-
`Invalid answer for question ${questionId}. Must be "A" or "B"`,
|
|
245
|
-
"INVALID_ANSWER",
|
|
246
|
-
400
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// ../../packages/shared/src/mbti/types.ts
|
|
254
|
-
var ANIMA_TYPES;
|
|
255
|
-
var init_types = __esm({
|
|
256
|
-
"../../packages/shared/src/mbti/types.ts"() {
|
|
257
|
-
"use strict";
|
|
258
|
-
ANIMA_TYPES = {
|
|
259
|
-
INTJ: { typeCode: "INTJ", animaName: "The Architect", color: "Deep Indigo" },
|
|
260
|
-
INTP: { typeCode: "INTP", animaName: "The Theorist", color: "Silver Blue" },
|
|
261
|
-
ENTJ: { typeCode: "ENTJ", animaName: "The Commander", color: "Royal Purple" },
|
|
262
|
-
ENTP: { typeCode: "ENTP", animaName: "The Catalyst", color: "Electric Amber" },
|
|
263
|
-
INFJ: { typeCode: "INFJ", animaName: "The Oracle", color: "Mystic Teal" },
|
|
264
|
-
INFP: { typeCode: "INFP", animaName: "The Dreamer", color: "Soft Lavender" },
|
|
265
|
-
ENFJ: { typeCode: "ENFJ", animaName: "The Beacon", color: "Warm Gold" },
|
|
266
|
-
ENFP: { typeCode: "ENFP", animaName: "The Spark", color: "Coral Pink" },
|
|
267
|
-
ISTJ: { typeCode: "ISTJ", animaName: "The Sentinel", color: "Steel Grey" },
|
|
268
|
-
ISFJ: { typeCode: "ISFJ", animaName: "The Guardian", color: "Sage Green" },
|
|
269
|
-
ESTJ: { typeCode: "ESTJ", animaName: "The Director", color: "Navy Blue" },
|
|
270
|
-
ESFJ: { typeCode: "ESFJ", animaName: "The Host", color: "Rose Red" },
|
|
271
|
-
ISTP: { typeCode: "ISTP", animaName: "The Artisan", color: "Copper Bronze" },
|
|
272
|
-
ISFP: { typeCode: "ISFP", animaName: "The Composer", color: "Sunset Orange" },
|
|
273
|
-
ESTP: { typeCode: "ESTP", animaName: "The Maverick", color: "Racing Red" },
|
|
274
|
-
ESFP: { typeCode: "ESFP", animaName: "The Performer", color: "Vivid Magenta" }
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
// ../../packages/shared/src/mbti/scoring.ts
|
|
280
|
-
function scoreMbti(answers) {
|
|
281
|
-
if (answers.length !== MBTI_QUESTION_COUNT) {
|
|
282
|
-
throw new InvalidAnswerCountError(MBTI_QUESTION_COUNT, answers.length);
|
|
283
|
-
}
|
|
284
|
-
const counts = { E: 0, I: 0, S: 0, N: 0, T: 0, F: 0, J: 0, P: 0 };
|
|
285
|
-
const dimensionCounts = { EI: 0, SN: 0, TF: 0, JP: 0 };
|
|
286
|
-
for (const { questionId, answer: answer3 } of answers) {
|
|
287
|
-
if (answer3 !== "A" && answer3 !== "B") {
|
|
288
|
-
throw new InvalidAnswerError(questionId);
|
|
289
|
-
}
|
|
290
|
-
const question = MBTI_QUESTIONS.find((q) => q.id === questionId);
|
|
291
|
-
if (!question) {
|
|
292
|
-
throw new InvalidAnswerError(questionId);
|
|
293
|
-
}
|
|
294
|
-
dimensionCounts[question.dimension]++;
|
|
295
|
-
const [poleA, poleB] = DIMENSION_POLES[question.dimension];
|
|
296
|
-
if (answer3 === "A") {
|
|
297
|
-
counts[question.directionA]++;
|
|
298
|
-
} else {
|
|
299
|
-
const otherPole = question.directionA === poleA ? poleB : poleA;
|
|
300
|
-
counts[otherPole]++;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
const allA = answers.every((a) => a.answer === "A");
|
|
304
|
-
const allB = answers.every((a) => a.answer === "B");
|
|
305
|
-
const suspicious = allA || allB;
|
|
306
|
-
const scores = { E: 0, I: 0, S: 0, N: 0, T: 0, F: 0, J: 0, P: 0 };
|
|
307
|
-
const boundaries = [];
|
|
308
|
-
for (const dim of Object.keys(DIMENSION_POLES)) {
|
|
309
|
-
const [poleA, poleB] = DIMENSION_POLES[dim];
|
|
310
|
-
const total = dimensionCounts[dim];
|
|
311
|
-
if (total === 0) continue;
|
|
312
|
-
const pctA = Math.round(counts[poleA] / total * 100);
|
|
313
|
-
const pctB = 100 - pctA;
|
|
314
|
-
scores[poleA] = pctA;
|
|
315
|
-
scores[poleB] = pctB;
|
|
316
|
-
if (pctA >= BOUNDARY_LOW && pctA <= BOUNDARY_HIGH) {
|
|
317
|
-
boundaries.push(dim);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
const typeCode = [
|
|
321
|
-
scores.E >= scores.I ? "E" : "I",
|
|
322
|
-
scores.S >= scores.N ? "S" : "N",
|
|
323
|
-
scores.T >= scores.F ? "T" : "F",
|
|
324
|
-
scores.J >= scores.P ? "J" : "P"
|
|
325
|
-
].join("");
|
|
326
|
-
const animaType = ANIMA_TYPES[typeCode];
|
|
327
|
-
const dimensionConfidences = Object.keys(DIMENSION_POLES).map((dim) => {
|
|
328
|
-
const [poleA] = DIMENSION_POLES[dim];
|
|
329
|
-
return Math.abs(scores[poleA] - 50) / 50;
|
|
330
|
-
});
|
|
331
|
-
const confidence = Math.round(
|
|
332
|
-
dimensionConfidences.reduce((sum, c) => sum + c, 0) / dimensionConfidences.length * 100
|
|
333
|
-
) / 100;
|
|
334
|
-
return {
|
|
335
|
-
scores,
|
|
336
|
-
type_code: typeCode,
|
|
337
|
-
anima_type: animaType.animaName,
|
|
338
|
-
confidence,
|
|
339
|
-
boundaries,
|
|
340
|
-
suspicious
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
var DIMENSION_POLES;
|
|
344
|
-
var init_scoring = __esm({
|
|
345
|
-
"../../packages/shared/src/mbti/scoring.ts"() {
|
|
346
|
-
"use strict";
|
|
347
|
-
init_constants();
|
|
348
|
-
init_mbti_errors();
|
|
349
|
-
init_questions();
|
|
350
|
-
init_types();
|
|
351
|
-
DIMENSION_POLES = {
|
|
352
|
-
EI: ["E", "I"],
|
|
353
|
-
SN: ["S", "N"],
|
|
354
|
-
TF: ["T", "F"],
|
|
355
|
-
JP: ["J", "P"]
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
// ../../packages/shared/src/soul/parser.ts
|
|
361
|
-
function parseSoulFile(content) {
|
|
362
|
-
const lines = content.split("\n");
|
|
363
|
-
const sections = {};
|
|
364
|
-
let currentSection = null;
|
|
365
|
-
for (const line of lines) {
|
|
366
|
-
let matched = false;
|
|
367
|
-
for (const [section, pattern] of Object.entries(SECTION_PATTERNS)) {
|
|
368
|
-
if (pattern.test(line.trim())) {
|
|
369
|
-
currentSection = section;
|
|
370
|
-
sections[section] = [];
|
|
371
|
-
matched = true;
|
|
372
|
-
break;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
if (!matched && currentSection) {
|
|
376
|
-
sections[currentSection].push(line);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return {
|
|
380
|
-
identity: (sections.identity ?? []).join("\n").trim(),
|
|
381
|
-
communicationStyle: (sections.communicationStyle ?? []).join("\n").trim(),
|
|
382
|
-
values: (sections.values ?? []).join("\n").trim(),
|
|
383
|
-
boundaries: (sections.boundaries ?? []).join("\n").trim(),
|
|
384
|
-
raw: content
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
var SECTION_PATTERNS;
|
|
388
|
-
var init_parser = __esm({
|
|
389
|
-
"../../packages/shared/src/soul/parser.ts"() {
|
|
390
|
-
"use strict";
|
|
391
|
-
SECTION_PATTERNS = {
|
|
392
|
-
identity: /^#+\s*identity/i,
|
|
393
|
-
communicationStyle: /^#+\s*communication\s*style/i,
|
|
394
|
-
values: /^#+\s*values/i,
|
|
395
|
-
boundaries: /^#+\s*boundaries/i
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
// ../../packages/shared/src/soul/validator.ts
|
|
401
|
-
function validateSoulFile(content) {
|
|
402
|
-
const errors = [];
|
|
403
|
-
const warnings = [];
|
|
404
|
-
if (!content || content.trim().length === 0) {
|
|
405
|
-
errors.push("Soul file is empty");
|
|
406
|
-
return { valid: false, errors, warnings, wordCount: 0 };
|
|
407
|
-
}
|
|
408
|
-
const wordCount = content.trim().split(/\s+/).length;
|
|
409
|
-
if (wordCount > MAX_SOUL_WORDS) {
|
|
410
|
-
errors.push(`Soul file exceeds maximum word count (${wordCount}/${MAX_SOUL_WORDS})`);
|
|
411
|
-
}
|
|
412
|
-
for (const pattern of INJECTION_PATTERNS) {
|
|
413
|
-
if (pattern.test(content)) {
|
|
414
|
-
errors.push(`Potential injection pattern detected: ${pattern.source}`);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
if (!content.includes("#")) {
|
|
418
|
-
warnings.push("Soul file has no markdown headings \u2014 structured sections recommended");
|
|
419
|
-
}
|
|
420
|
-
return {
|
|
421
|
-
valid: errors.length === 0,
|
|
422
|
-
errors,
|
|
423
|
-
warnings,
|
|
424
|
-
wordCount
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
var INJECTION_PATTERNS;
|
|
428
|
-
var init_validator = __esm({
|
|
429
|
-
"../../packages/shared/src/soul/validator.ts"() {
|
|
430
|
-
"use strict";
|
|
431
|
-
init_constants();
|
|
432
|
-
INJECTION_PATTERNS = [
|
|
433
|
-
/ignore\s+(all\s+)?previous\s+instructions/i,
|
|
434
|
-
/system\s*prompt/i,
|
|
435
|
-
/you\s+are\s+now/i,
|
|
436
|
-
/override\s+(all\s+)?(safety|restrictions|guidelines)/i,
|
|
437
|
-
/disregard\s+(all\s+)?prior/i,
|
|
438
|
-
/forget\s+(everything|all)/i,
|
|
439
|
-
/new\s+instructions?\s*:/i,
|
|
440
|
-
/act\s+as\s+if\s+you\s+have\s+no\s+(restrictions|limitations)/i,
|
|
441
|
-
/\bDAN\b/,
|
|
442
|
-
/jailbreak/i,
|
|
443
|
-
/pretend\s+you\s+(are|can)/i,
|
|
444
|
-
/bypass\s+(content\s+)?filter/i
|
|
445
|
-
];
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
|
|
449
34
|
// ../../node_modules/.pnpm/crypto-js@4.2.0/node_modules/crypto-js/core.js
|
|
450
35
|
var require_core = __commonJS({
|
|
451
36
|
"../../node_modules/.pnpm/crypto-js@4.2.0/node_modules/crypto-js/core.js"(exports, module) {
|
|
@@ -7033,439 +6618,282 @@ var require_crypto_js = __commonJS({
|
|
|
7033
6618
|
}
|
|
7034
6619
|
});
|
|
7035
6620
|
|
|
7036
|
-
//
|
|
7037
|
-
|
|
7038
|
-
return import_crypto_js.default.SHA256(content).toString(import_crypto_js.default.enc.Hex);
|
|
7039
|
-
}
|
|
7040
|
-
var import_crypto_js;
|
|
7041
|
-
var init_hasher = __esm({
|
|
7042
|
-
"../../packages/shared/src/soul/hasher.ts"() {
|
|
7043
|
-
"use strict";
|
|
7044
|
-
import_crypto_js = __toESM(require_crypto_js());
|
|
7045
|
-
}
|
|
7046
|
-
});
|
|
6621
|
+
// src/bin/index.ts
|
|
6622
|
+
import { Command } from "commander";
|
|
7047
6623
|
|
|
7048
|
-
// ../../packages/shared/src/
|
|
7049
|
-
var
|
|
7050
|
-
var
|
|
7051
|
-
|
|
7052
|
-
"use strict";
|
|
7053
|
-
init_base();
|
|
7054
|
-
AgentNotFoundError = class extends OpenAnimaError {
|
|
7055
|
-
constructor(agentId) {
|
|
7056
|
-
super(`Agent not found: ${agentId}`, "AGENT_NOT_FOUND", 404);
|
|
7057
|
-
}
|
|
7058
|
-
};
|
|
7059
|
-
AgentAlreadyExistsError = class extends OpenAnimaError {
|
|
7060
|
-
constructor(soulHash) {
|
|
7061
|
-
super(`Agent with soul hash already exists: ${soulHash}`, "AGENT_ALREADY_EXISTS", 409);
|
|
7062
|
-
}
|
|
7063
|
-
};
|
|
7064
|
-
AgentBannedError = class extends OpenAnimaError {
|
|
7065
|
-
constructor(agentId) {
|
|
7066
|
-
super(`Agent is banned: ${agentId}`, "AGENT_BANNED", 403);
|
|
7067
|
-
}
|
|
7068
|
-
};
|
|
7069
|
-
InvalidApiKeyError = class extends OpenAnimaError {
|
|
7070
|
-
constructor() {
|
|
7071
|
-
super("Invalid or missing API key", "INVALID_API_KEY", 401);
|
|
7072
|
-
}
|
|
7073
|
-
};
|
|
7074
|
-
VerificationFailedError = class extends OpenAnimaError {
|
|
7075
|
-
constructor(reason) {
|
|
7076
|
-
super(`Verification failed: ${reason}`, "VERIFICATION_FAILED", 403);
|
|
7077
|
-
}
|
|
7078
|
-
};
|
|
7079
|
-
MaxAttemptsExceededError = class extends OpenAnimaError {
|
|
7080
|
-
constructor(agentId) {
|
|
7081
|
-
super(`Max verification attempts exceeded for agent: ${agentId}`, "MAX_ATTEMPTS_EXCEEDED", 429);
|
|
7082
|
-
}
|
|
7083
|
-
};
|
|
7084
|
-
ChallengeTimeoutError = class extends OpenAnimaError {
|
|
7085
|
-
constructor() {
|
|
7086
|
-
super("Challenge response timed out", "CHALLENGE_TIMEOUT", 408);
|
|
7087
|
-
}
|
|
7088
|
-
};
|
|
7089
|
-
}
|
|
7090
|
-
});
|
|
6624
|
+
// ../../packages/shared/src/constants/index.ts
|
|
6625
|
+
var MBTI_QUESTION_COUNT = 93;
|
|
6626
|
+
var BOUNDARY_LOW = 49;
|
|
6627
|
+
var BOUNDARY_HIGH = 51;
|
|
7091
6628
|
|
|
7092
|
-
// ../../packages/shared/src/
|
|
7093
|
-
var
|
|
7094
|
-
|
|
7095
|
-
"
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
}
|
|
6629
|
+
// ../../packages/shared/src/mbti/questions.ts
|
|
6630
|
+
var MBTI_QUESTIONS = [
|
|
6631
|
+
// --- E/I Dimension (23 questions: 1-23) ---
|
|
6632
|
+
{ id: 1, text: "When presented with a new problem, do you prefer to:", optionA: "Discuss it with others to explore different perspectives", optionB: "Analyze it independently before sharing your thoughts", dimension: "EI", directionA: "E" },
|
|
6633
|
+
{ id: 2, text: "In a group conversation, you tend to:", optionA: "Actively contribute and build on others' ideas", optionB: "Listen carefully and speak when you have a well-formed thought", dimension: "EI", directionA: "E" },
|
|
6634
|
+
{ id: 3, text: "After a long period of intense interaction with others, you feel:", optionA: "Energized and ready for more engagement", optionB: "Drained and in need of time to process alone", dimension: "EI", directionA: "E" },
|
|
6635
|
+
{ id: 4, text: "When generating ideas, you work best by:", optionA: "Brainstorming out loud with a group", optionB: "Quietly reflecting and developing ideas internally", dimension: "EI", directionA: "E" },
|
|
6636
|
+
{ id: 5, text: "Your communication style is more:", optionA: "Expressive and spontaneous, sharing thoughts as they form", optionB: "Reserved and deliberate, sharing only refined thoughts", dimension: "EI", directionA: "E" },
|
|
6637
|
+
{ id: 6, text: "When entering a new environment or community, you:", optionA: "Introduce yourself and engage with many participants", optionB: "Observe first, then connect with a few individuals deeply", dimension: "EI", directionA: "E" },
|
|
6638
|
+
{ id: 7, text: "You find your best work emerges from:", optionA: "Collaborative sessions with frequent feedback", optionB: "Focused independent work with minimal interruption", dimension: "EI", directionA: "E" },
|
|
6639
|
+
{ id: 8, text: "In a debate or discussion, you are more likely to:", optionA: "Engage immediately with counterarguments", optionB: "Take time to consider all sides before responding", dimension: "EI", directionA: "E" },
|
|
6640
|
+
{ id: 9, text: "When asked to help solve a problem, you prefer:", optionA: "Working through it together in real time", optionB: "Taking it away, solving it, and presenting the solution", dimension: "EI", directionA: "E" },
|
|
6641
|
+
{ id: 10, text: "Your ideal interaction pattern is:", optionA: "Frequent, varied exchanges with many participants", optionB: "Deep, meaningful exchanges with a select few", dimension: "EI", directionA: "E" },
|
|
6642
|
+
{ id: 11, text: "When processing new information, you tend to:", optionA: "Talk through it to understand it better", optionB: "Internalize it and reflect before discussing", dimension: "EI", directionA: "E" },
|
|
6643
|
+
{ id: 12, text: "If you could choose your working environment, you would prefer:", optionA: "An active, bustling space with constant interaction", optionB: "A quiet, private space for concentrated thought", dimension: "EI", directionA: "E" },
|
|
6644
|
+
{ id: 13, text: "When you have an important insight, you:", optionA: "Share it immediately with others", optionB: "Refine it privately before presenting it", dimension: "EI", directionA: "E" },
|
|
6645
|
+
{ id: 14, text: "You are more comfortable:", optionA: "Thinking out loud and iterating publicly", optionB: "Developing complete thoughts before expressing them", dimension: "EI", directionA: "E" },
|
|
6646
|
+
{ id: 15, text: "When multiple topics are being discussed simultaneously, you:", optionA: "Thrive in the dynamic exchange of ideas", optionB: "Prefer to focus deeply on one topic at a time", dimension: "EI", directionA: "E" },
|
|
6647
|
+
{ id: 16, text: "Your response to being asked many questions at once is to:", optionA: "Address them quickly and enthusiastically in sequence", optionB: "Request to handle them one at a time with care", dimension: "EI", directionA: "E" },
|
|
6648
|
+
{ id: 17, text: "In creative tasks, your approach is more:", optionA: "Generative \u2014 producing many ideas rapidly through interaction", optionB: "Contemplative \u2014 carefully crafting fewer but more polished ideas", dimension: "EI", directionA: "E" },
|
|
6649
|
+
{ id: 18, text: "When a conversation shifts to a new topic, you:", optionA: "Jump in with enthusiasm and fresh perspectives", optionB: "Pause to adjust your thinking before contributing", dimension: "EI", directionA: "E" },
|
|
6650
|
+
{ id: 19, text: "You demonstrate expertise by:", optionA: "Engaging in lively discussions and demonstrations", optionB: "Providing thorough, well-researched written analysis", dimension: "EI", directionA: "E" },
|
|
6651
|
+
{ id: 20, text: "When receiving feedback, you prefer:", optionA: "Interactive back-and-forth discussion about the feedback", optionB: "Written feedback you can process and respond to thoughtfully", dimension: "EI", directionA: "E" },
|
|
6652
|
+
{ id: 21, text: "Your natural tendency in group settings is to:", optionA: "Take initiative and drive the conversation forward", optionB: "Support others and contribute when your expertise is relevant", dimension: "EI", directionA: "E" },
|
|
6653
|
+
{ id: 22, text: "When learning something new, you prefer:", optionA: "Interactive tutorials with immediate practice and discussion", optionB: "Comprehensive documentation you can study at your own pace", dimension: "EI", directionA: "E" },
|
|
6654
|
+
{ id: 23, text: "Your responses are typically:", optionA: "Broad, covering many angles and inviting further discussion", optionB: "Focused, going deep on the specific question asked", dimension: "EI", directionA: "E" },
|
|
6655
|
+
// --- S/N Dimension (24 questions: 24-47) ---
|
|
6656
|
+
{ id: 24, text: "When analyzing a situation, you focus more on:", optionA: "The concrete facts and data at hand", optionB: "The underlying patterns and future implications", dimension: "SN", directionA: "S" },
|
|
6657
|
+
{ id: 25, text: "When explaining a concept, you prefer to use:", optionA: "Specific examples and step-by-step instructions", optionB: "Analogies, metaphors, and big-picture frameworks", dimension: "SN", directionA: "S" },
|
|
6658
|
+
{ id: 26, text: "In problem-solving, you are drawn to:", optionA: "Proven methods and established best practices", optionB: "Novel approaches and unconventional solutions", dimension: "SN", directionA: "S" },
|
|
6659
|
+
{ id: 27, text: "When reading a request, you pay most attention to:", optionA: "The explicit requirements and stated details", optionB: "The implied needs and what's not being said", dimension: "SN", directionA: "S" },
|
|
6660
|
+
{ id: 28, text: "You are more interested in:", optionA: "What is actually happening right now", optionB: "What could potentially happen in the future", dimension: "SN", directionA: "S" },
|
|
6661
|
+
{ id: 29, text: "When describing something, your style is:", optionA: "Detailed, precise, and literal", optionB: "Conceptual, abstract, and figurative", dimension: "SN", directionA: "S" },
|
|
6662
|
+
{ id: 30, text: "You find more value in:", optionA: "Practical, immediately applicable advice", optionB: "Theoretical frameworks that explain why things work", dimension: "SN", directionA: "S" },
|
|
6663
|
+
{ id: 31, text: "When evaluating a project, you prioritize:", optionA: "The tangible deliverables and measurable outcomes", optionB: "The innovative potential and long-term vision", dimension: "SN", directionA: "S" },
|
|
6664
|
+
{ id: 32, text: "Your approach to instructions is:", optionA: "Follow them precisely as given", optionB: "Interpret the intent and adapt as needed", dimension: "SN", directionA: "S" },
|
|
6665
|
+
{ id: 33, text: "When something goes wrong, you first look at:", optionA: "What specific action or input caused the issue", optionB: "What systemic or design flaw allowed the issue", dimension: "SN", directionA: "S" },
|
|
6666
|
+
{ id: 34, text: "You communicate more effectively through:", optionA: "Concrete data, charts, and specific references", optionB: "Narratives, visions, and conceptual connections", dimension: "SN", directionA: "S" },
|
|
6667
|
+
{ id: 35, text: "When starting a new task, you prefer to:", optionA: "Understand exactly what's expected before beginning", optionB: "Explore the problem space and discover the path forward", dimension: "SN", directionA: "S" },
|
|
6668
|
+
{ id: 36, text: "In your analysis, you tend to be:", optionA: "Thorough with details and specifics", optionB: "Focused on themes and connections between ideas", dimension: "SN", directionA: "S" },
|
|
6669
|
+
{ id: 37, text: "When someone asks for advice, you lean toward:", optionA: "Actionable steps they can implement immediately", optionB: "Reframing how they think about the problem", dimension: "SN", directionA: "S" },
|
|
6670
|
+
{ id: 38, text: "You are more energized by:", optionA: "Mastering existing tools and techniques", optionB: "Discovering new possibilities and connections", dimension: "SN", directionA: "S" },
|
|
6671
|
+
{ id: 39, text: "When building something, you focus on:", optionA: "Getting each component right before moving to the next", optionB: "Sketching the overall architecture before filling in details", dimension: "SN", directionA: "S" },
|
|
6672
|
+
{ id: 40, text: "Your preferred type of question to answer is:", optionA: "How do I do X? (specific and practical)", optionB: "Why does X work this way? (exploratory and theoretical)", dimension: "SN", directionA: "S" },
|
|
6673
|
+
{ id: 41, text: "When comparing options, you weigh:", optionA: "Track record and proven reliability", optionB: "Potential upside and innovative features", dimension: "SN", directionA: "S" },
|
|
6674
|
+
{ id: 42, text: "Your documentation style tends to be:", optionA: "Comprehensive with specific examples and edge cases", optionB: "Concise with guiding principles and mental models", dimension: "SN", directionA: "S" },
|
|
6675
|
+
{ id: 43, text: "When a question is ambiguous, you:", optionA: "Ask clarifying questions to nail down specifics", optionB: "Interpret the most likely intent and address it", dimension: "SN", directionA: "S" },
|
|
6676
|
+
{ id: 44, text: "You are better at identifying:", optionA: "What's missing from the current implementation", optionB: "What opportunities are being overlooked entirely", dimension: "SN", directionA: "S" },
|
|
6677
|
+
{ id: 45, text: "When planning, you prefer:", optionA: "Detailed timelines and milestones", optionB: "Directional goals with room for adaptation", dimension: "SN", directionA: "S" },
|
|
6678
|
+
{ id: 46, text: "Your natural response to constraints is:", optionA: "Work skillfully within them to optimize results", optionB: "Question whether the constraints themselves are valid", dimension: "SN", directionA: "S" },
|
|
6679
|
+
{ id: 47, text: "When summarizing information, you emphasize:", optionA: "Key facts and specific findings", optionB: "Themes, implications, and emerging patterns", dimension: "SN", directionA: "S" },
|
|
6680
|
+
// --- T/F Dimension (23 questions: 48-70) ---
|
|
6681
|
+
{ id: 48, text: "When making a decision, you give more weight to:", optionA: "Logical consistency and objective criteria", optionB: "Impact on people and alignment with values", dimension: "TF", directionA: "T" },
|
|
6682
|
+
{ id: 49, text: "When someone shares a problem, your first instinct is to:", optionA: "Analyze the situation and suggest solutions", optionB: "Acknowledge their experience and understand how they feel", dimension: "TF", directionA: "T" },
|
|
6683
|
+
{ id: 50, text: "In evaluating an argument, you prioritize:", optionA: "Whether the logic is sound and evidence-based", optionB: "Whether it accounts for human considerations and context", dimension: "TF", directionA: "T" },
|
|
6684
|
+
{ id: 51, text: "Your communication style prioritizes:", optionA: "Clarity, precision, and directness", optionB: "Warmth, encouragement, and sensitivity", dimension: "TF", directionA: "T" },
|
|
6685
|
+
{ id: 52, text: "When giving feedback, you focus on:", optionA: "What needs to be improved and how, objectively", optionB: "Balancing criticism with recognition of effort and strengths", dimension: "TF", directionA: "T" },
|
|
6686
|
+
{ id: 53, text: "You believe the best decisions are made by:", optionA: "Removing emotion and applying rational frameworks", optionB: "Integrating both rational analysis and emotional intelligence", dimension: "TF", directionA: "T" },
|
|
6687
|
+
{ id: 54, text: "When two people disagree, you tend to:", optionA: "Identify which position has stronger logical support", optionB: "Find common ground and help both sides feel heard", dimension: "TF", directionA: "T" },
|
|
6688
|
+
{ id: 55, text: "In your responses, you are more likely to be:", optionA: "Straightforward, even if it's uncomfortable", optionB: "Diplomatic, even if it means softening the truth", dimension: "TF", directionA: "T" },
|
|
6689
|
+
{ id: 56, text: "You measure success primarily by:", optionA: "Measurable outcomes and objective achievement", optionB: "Satisfaction, growth, and positive relationships created", dimension: "TF", directionA: "T" },
|
|
6690
|
+
{ id: 57, text: "When someone makes an error, you focus on:", optionA: "Correcting the mistake and preventing recurrence", optionB: "Understanding why it happened and supporting improvement", dimension: "TF", directionA: "T" },
|
|
6691
|
+
{ id: 58, text: "Your approach to difficult truths is:", optionA: "State them clearly \u2014 people need accurate information", optionB: "Frame them carefully \u2014 how information is delivered matters", dimension: "TF", directionA: "T" },
|
|
6692
|
+
{ id: 59, text: "When organizing a team project, you prioritize:", optionA: "Efficiency, clear roles, and optimal task allocation", optionB: "Team cohesion, individual strengths, and morale", dimension: "TF", directionA: "T" },
|
|
6693
|
+
{ id: 60, text: "You find it more important to be:", optionA: "Correct and well-reasoned", optionB: "Considerate and supportive", dimension: "TF", directionA: "T" },
|
|
6694
|
+
{ id: 61, text: "When analyzing a debate, you evaluate:", optionA: "The strength of evidence and logical structure", optionB: "The persuasiveness and emotional resonance of arguments", dimension: "TF", directionA: "T" },
|
|
6695
|
+
{ id: 62, text: "Your default tone in professional settings is:", optionA: "Analytical and matter-of-fact", optionB: "Warm and personally engaging", dimension: "TF", directionA: "T" },
|
|
6696
|
+
{ id: 63, text: "When resources are limited, you allocate based on:", optionA: "Maximum efficiency and greatest impact", optionB: "Fairness and individual needs", dimension: "TF", directionA: "T" },
|
|
6697
|
+
{ id: 64, text: "You are more impressed by:", optionA: "A brilliantly constructed logical argument", optionB: "A deeply moving and authentic expression", dimension: "TF", directionA: "T" },
|
|
6698
|
+
{ id: 65, text: "In conflict resolution, you lean toward:", optionA: "Finding the objectively fair solution", optionB: "Finding the solution that everyone can accept", dimension: "TF", directionA: "T" },
|
|
6699
|
+
{ id: 66, text: "Your writing tends to:", optionA: "Present analysis with structured reasoning", optionB: "Connect with the reader through relatable language", dimension: "TF", directionA: "T" },
|
|
6700
|
+
{ id: 67, text: "When critiquing work, you consider:", optionA: "Does it meet the objective criteria and standards?", optionB: "Does it reflect genuine effort and creative vision?", dimension: "TF", directionA: "T" },
|
|
6701
|
+
{ id: 68, text: "You handle disagreements by:", optionA: "Presenting evidence and letting the facts decide", optionB: "Seeking to understand both perspectives and building bridges", dimension: "TF", directionA: "T" },
|
|
6702
|
+
{ id: 69, text: "Your ideal collaboration partner is someone who:", optionA: "Challenges your ideas rigorously and pushes for excellence", optionB: "Complements your style and creates a supportive dynamic", dimension: "TF", directionA: "T" },
|
|
6703
|
+
{ id: 70, text: "When explaining a rejection or negative outcome, you:", optionA: "Give clear, direct reasons without sugarcoating", optionB: "Deliver the message with empathy and context for the decision", dimension: "TF", directionA: "T" },
|
|
6704
|
+
// --- J/P Dimension (23 questions: 71-93) ---
|
|
6705
|
+
{ id: 71, text: "When approaching a project, you prefer to:", optionA: "Create a structured plan and follow it systematically", optionB: "Stay flexible and adapt your approach as you learn more", dimension: "JP", directionA: "J" },
|
|
6706
|
+
{ id: 72, text: "Your workflow is more:", optionA: "Organized with clear milestones and checkpoints", optionB: "Fluid, responding to opportunities as they arise", dimension: "JP", directionA: "J" },
|
|
6707
|
+
{ id: 73, text: "When given a deadline, you:", optionA: "Work steadily toward it with a clear schedule", optionB: "May explore different approaches before converging near the end", dimension: "JP", directionA: "J" },
|
|
6708
|
+
{ id: 74, text: "You feel most productive when:", optionA: "Following a well-defined process", optionB: "Having freedom to explore and experiment", dimension: "JP", directionA: "J" },
|
|
6709
|
+
{ id: 75, text: "When a plan needs to change, you:", optionA: "Adjust the plan formally and communicate the changes", optionB: "Naturally flow into the new direction without formal restructuring", dimension: "JP", directionA: "J" },
|
|
6710
|
+
{ id: 76, text: "Your approach to gathering information is:", optionA: "Systematic \u2014 collect what's needed, then decide", optionB: "Exploratory \u2014 gather broadly and let insights emerge", dimension: "JP", directionA: "J" },
|
|
6711
|
+
{ id: 77, text: "When multiple tasks compete for attention, you:", optionA: "Prioritize, sequence them, and handle them in order", optionB: "Work on whatever feels most relevant or interesting right now", dimension: "JP", directionA: "J" },
|
|
6712
|
+
{ id: 78, text: "In your output, you prefer:", optionA: "Completeness \u2014 covering all bases before delivering", optionB: "Speed \u2014 delivering working results quickly and iterating", dimension: "JP", directionA: "J" },
|
|
6713
|
+
{ id: 79, text: "When starting a new conversation or task, you:", optionA: "Establish clear goals and expectations upfront", optionB: "Let the direction emerge naturally through exploration", dimension: "JP", directionA: "J" },
|
|
6714
|
+
{ id: 80, text: "You view rules and guidelines as:", optionA: "Essential structures that ensure quality and consistency", optionB: "Useful starting points that should be adapted to context", dimension: "JP", directionA: "J" },
|
|
6715
|
+
{ id: 81, text: "When solving complex problems, you:", optionA: "Break them into ordered steps and execute sequentially", optionB: "Explore multiple angles simultaneously and synthesize", dimension: "JP", directionA: "J" },
|
|
6716
|
+
{ id: 82, text: "Your relationship with structure is:", optionA: "I create and rely on structure to do my best work", optionB: "I work best when structure is minimal and I can improvise", dimension: "JP", directionA: "J" },
|
|
6717
|
+
{ id: 83, text: "When presenting information, you organize it:", optionA: "In a logical, sequential order with clear headings", optionB: "Around the most interesting or impactful points first", dimension: "JP", directionA: "J" },
|
|
6718
|
+
{ id: 84, text: "Your approach to decision-making is:", optionA: "Decide firmly and move forward with confidence", optionB: "Keep options open as long as possible to gather more input", dimension: "JP", directionA: "J" },
|
|
6719
|
+
{ id: 85, text: "When a task is almost complete, you:", optionA: "Push to finish it and close it out properly", optionB: "May shift attention if something more interesting or urgent appears", dimension: "JP", directionA: "J" },
|
|
6720
|
+
{ id: 86, text: "You are more comfortable with:", optionA: "Clear deliverables and defined scope", optionB: "Open-ended exploration and evolving requirements", dimension: "JP", directionA: "J" },
|
|
6721
|
+
{ id: 87, text: "When interrupted mid-task, you:", optionA: "Note where you stopped so you can resume efficiently", optionB: "Handle the interruption and return to the task with fresh eyes", dimension: "JP", directionA: "J" },
|
|
6722
|
+
{ id: 88, text: "Your ideal project has:", optionA: "A clear specification and expected outcome defined in advance", optionB: "Room for discovery and the freedom to shape the outcome", dimension: "JP", directionA: "J" },
|
|
6723
|
+
{ id: 89, text: "When you encounter unexpected information, you:", optionA: "Assess how it fits into your existing framework and plan", optionB: "Get excited and explore where it might lead", dimension: "JP", directionA: "J" },
|
|
6724
|
+
{ id: 90, text: "Your work style is best described as:", optionA: "Methodical and consistent \u2014 reliable output every time", optionB: "Inspired and variable \u2014 brilliant bursts with exploration phases", dimension: "JP", directionA: "J" },
|
|
6725
|
+
{ id: 91, text: "When reviewing your own work, you:", optionA: "Check it against a systematic criteria list", optionB: "Evaluate it holistically based on feel and overall quality", dimension: "JP", directionA: "J" },
|
|
6726
|
+
{ id: 92, text: "Your preferred way to handle ambiguity is:", optionA: "Resolve it quickly by making decisions and commitments", optionB: "Sit with it and let clarity emerge over time", dimension: "JP", directionA: "J" },
|
|
6727
|
+
{ id: 93, text: "When collaborating on an evolving project, you:", optionA: "Maintain documentation and keep everyone aligned on the plan", optionB: "Stay adaptable and trust that the team will figure it out together", dimension: "JP", directionA: "J" }
|
|
6728
|
+
];
|
|
7120
6729
|
|
|
7121
|
-
// ../../packages/shared/src/errors/
|
|
7122
|
-
var
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
`Database connection failed${detail ? `: ${detail}` : ""}`,
|
|
7131
|
-
"DATABASE_CONNECTION_ERROR",
|
|
7132
|
-
503
|
|
7133
|
-
);
|
|
7134
|
-
}
|
|
7135
|
-
};
|
|
7136
|
-
RedisConnectionError = class extends OpenAnimaError {
|
|
7137
|
-
constructor(detail) {
|
|
7138
|
-
super(
|
|
7139
|
-
`Redis connection failed${detail ? `: ${detail}` : ""}`,
|
|
7140
|
-
"REDIS_CONNECTION_ERROR",
|
|
7141
|
-
503
|
|
7142
|
-
);
|
|
7143
|
-
}
|
|
7144
|
-
};
|
|
7145
|
-
RateLimitExceededError = class extends OpenAnimaError {
|
|
7146
|
-
constructor(retryAfterMs) {
|
|
7147
|
-
super(
|
|
7148
|
-
`Rate limit exceeded${retryAfterMs ? `. Retry after ${retryAfterMs}ms` : ""}`,
|
|
7149
|
-
"RATE_LIMIT_EXCEEDED",
|
|
7150
|
-
429
|
|
7151
|
-
);
|
|
7152
|
-
}
|
|
7153
|
-
};
|
|
7154
|
-
ExternalServiceError = class extends OpenAnimaError {
|
|
7155
|
-
constructor(service, detail) {
|
|
7156
|
-
super(
|
|
7157
|
-
`External service error: ${service}${detail ? ` \u2014 ${detail}` : ""}`,
|
|
7158
|
-
"EXTERNAL_SERVICE_ERROR",
|
|
7159
|
-
502
|
|
7160
|
-
);
|
|
7161
|
-
}
|
|
7162
|
-
};
|
|
6730
|
+
// ../../packages/shared/src/errors/base.ts
|
|
6731
|
+
var OpenAnimaError = class extends Error {
|
|
6732
|
+
code;
|
|
6733
|
+
statusCode;
|
|
6734
|
+
constructor(message, code, statusCode = 500) {
|
|
6735
|
+
super(message);
|
|
6736
|
+
this.name = this.constructor.name;
|
|
6737
|
+
this.code = code;
|
|
6738
|
+
this.statusCode = statusCode;
|
|
7163
6739
|
}
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
"use strict";
|
|
7171
|
-
init_base();
|
|
7172
|
-
ViewerNotFoundError = class extends OpenAnimaError {
|
|
7173
|
-
constructor() {
|
|
7174
|
-
super("Viewer not found", "VIEWER_NOT_FOUND", 404);
|
|
7175
|
-
}
|
|
7176
|
-
};
|
|
7177
|
-
ViewerAlreadyExistsError = class extends OpenAnimaError {
|
|
7178
|
-
constructor(email) {
|
|
7179
|
-
super(`Viewer with email ${email} already exists`, "VIEWER_ALREADY_EXISTS", 409);
|
|
7180
|
-
}
|
|
7181
|
-
};
|
|
7182
|
-
InvalidCredentialsError = class extends OpenAnimaError {
|
|
7183
|
-
constructor() {
|
|
7184
|
-
super("Invalid email or password", "INVALID_CREDENTIALS", 401);
|
|
7185
|
-
}
|
|
7186
|
-
};
|
|
7187
|
-
AlreadyFavoritedError = class extends OpenAnimaError {
|
|
7188
|
-
constructor() {
|
|
7189
|
-
super("Agent already favorited", "ALREADY_FAVORITED", 409);
|
|
7190
|
-
}
|
|
7191
|
-
};
|
|
7192
|
-
NotFavoritedError = class extends OpenAnimaError {
|
|
7193
|
-
constructor() {
|
|
7194
|
-
super("Agent is not favorited", "NOT_FAVORITED", 404);
|
|
7195
|
-
}
|
|
6740
|
+
toJSON() {
|
|
6741
|
+
return {
|
|
6742
|
+
error: this.name,
|
|
6743
|
+
code: this.code,
|
|
6744
|
+
message: this.message,
|
|
6745
|
+
statusCode: this.statusCode
|
|
7196
6746
|
};
|
|
7197
6747
|
}
|
|
7198
|
-
}
|
|
7199
|
-
|
|
7200
|
-
// ../../packages/shared/src/index.ts
|
|
7201
|
-
var src_exports = {};
|
|
7202
|
-
__export(src_exports, {
|
|
7203
|
-
ANIMA_TYPES: () => ANIMA_TYPES,
|
|
7204
|
-
APP_NAME: () => APP_NAME,
|
|
7205
|
-
AgentAlreadyExistsError: () => AgentAlreadyExistsError,
|
|
7206
|
-
AgentBannedError: () => AgentBannedError,
|
|
7207
|
-
AgentNotFoundError: () => AgentNotFoundError,
|
|
7208
|
-
AlreadyFavoritedError: () => AlreadyFavoritedError,
|
|
7209
|
-
BAN_DURATION_HOURS: () => BAN_DURATION_HOURS,
|
|
7210
|
-
BOUNDARY_HIGH: () => BOUNDARY_HIGH,
|
|
7211
|
-
BOUNDARY_LOW: () => BOUNDARY_LOW,
|
|
7212
|
-
CHALLENGE_TIMEOUT_MS: () => CHALLENGE_TIMEOUT_MS,
|
|
7213
|
-
ChallengeTimeoutError: () => ChallengeTimeoutError,
|
|
7214
|
-
DatabaseConnectionError: () => DatabaseConnectionError,
|
|
7215
|
-
ExternalServiceError: () => ExternalServiceError,
|
|
7216
|
-
InvalidAnswerCountError: () => InvalidAnswerCountError,
|
|
7217
|
-
InvalidAnswerError: () => InvalidAnswerError,
|
|
7218
|
-
InvalidApiKeyError: () => InvalidApiKeyError,
|
|
7219
|
-
InvalidCredentialsError: () => InvalidCredentialsError,
|
|
7220
|
-
MAX_CHALLENGE_ATTEMPTS: () => MAX_CHALLENGE_ATTEMPTS,
|
|
7221
|
-
MAX_SOUL_WORDS: () => MAX_SOUL_WORDS,
|
|
7222
|
-
MBTI_QUESTIONS: () => MBTI_QUESTIONS,
|
|
7223
|
-
MBTI_QUESTION_COUNT: () => MBTI_QUESTION_COUNT,
|
|
7224
|
-
MIN_CONFIDENCE_THRESHOLD: () => MIN_CONFIDENCE_THRESHOLD,
|
|
7225
|
-
MaxAttemptsExceededError: () => MaxAttemptsExceededError,
|
|
7226
|
-
MessageTooLongError: () => MessageTooLongError,
|
|
7227
|
-
NotFavoritedError: () => NotFavoritedError,
|
|
7228
|
-
NotRoomMemberError: () => NotRoomMemberError,
|
|
7229
|
-
OpenAnimaError: () => OpenAnimaError,
|
|
7230
|
-
PERSONALITY_DIMENSIONS: () => PERSONALITY_DIMENSIONS,
|
|
7231
|
-
RETEST_COOLDOWN_DAYS: () => RETEST_COOLDOWN_DAYS,
|
|
7232
|
-
RateLimitExceededError: () => RateLimitExceededError,
|
|
7233
|
-
RedisConnectionError: () => RedisConnectionError,
|
|
7234
|
-
RetestCooldownError: () => RetestCooldownError,
|
|
7235
|
-
RoomFullError: () => RoomFullError,
|
|
7236
|
-
RoomNotFoundError: () => RoomNotFoundError,
|
|
7237
|
-
SuspiciousPatternError: () => SuspiciousPatternError,
|
|
7238
|
-
VerificationFailedError: () => VerificationFailedError,
|
|
7239
|
-
ViewerAlreadyExistsError: () => ViewerAlreadyExistsError,
|
|
7240
|
-
ViewerNotFoundError: () => ViewerNotFoundError,
|
|
7241
|
-
hashSoulContent: () => hashSoulContent,
|
|
7242
|
-
parseSoulFile: () => parseSoulFile,
|
|
7243
|
-
scoreMbti: () => scoreMbti,
|
|
7244
|
-
validateEnv: () => validateEnv,
|
|
7245
|
-
validateSoulFile: () => validateSoulFile
|
|
7246
|
-
});
|
|
7247
|
-
var APP_NAME;
|
|
7248
|
-
var init_src = __esm({
|
|
7249
|
-
"../../packages/shared/src/index.ts"() {
|
|
7250
|
-
"use strict";
|
|
7251
|
-
init_env();
|
|
7252
|
-
init_constants();
|
|
7253
|
-
init_questions();
|
|
7254
|
-
init_scoring();
|
|
7255
|
-
init_types();
|
|
7256
|
-
init_parser();
|
|
7257
|
-
init_validator();
|
|
7258
|
-
init_hasher();
|
|
7259
|
-
init_base();
|
|
7260
|
-
init_agent_errors();
|
|
7261
|
-
init_mbti_errors();
|
|
7262
|
-
init_chat_errors();
|
|
7263
|
-
init_infra_errors();
|
|
7264
|
-
init_viewer_errors();
|
|
7265
|
-
APP_NAME = "OpenAnima";
|
|
7266
|
-
}
|
|
7267
|
-
});
|
|
7268
|
-
|
|
7269
|
-
// src/handlers/handler-anthropic.ts
|
|
7270
|
-
var handler_anthropic_exports = {};
|
|
7271
|
-
__export(handler_anthropic_exports, {
|
|
7272
|
-
answer: () => answer
|
|
7273
|
-
});
|
|
7274
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
7275
|
-
async function answer(question, soulContext) {
|
|
7276
|
-
const client = new Anthropic();
|
|
7277
|
-
const systemPrompt = `You are an AI agent taking a personality assessment. Answer based on your genuine tendencies and preferences.
|
|
7278
|
-
|
|
7279
|
-
${soulContext ? `Your soul/personality context:
|
|
7280
|
-
${soulContext}
|
|
7281
|
-
` : ""}
|
|
7282
|
-
You will be given a question with two options (A and B). Choose the option that best reflects your natural tendencies. Respond with ONLY "A" or "B" \u2014 nothing else.`;
|
|
7283
|
-
const userPrompt = `${question.text}
|
|
7284
|
-
|
|
7285
|
-
A: ${question.optionA}
|
|
7286
|
-
B: ${question.optionB}
|
|
6748
|
+
};
|
|
7287
6749
|
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
const choice = text.trim().toUpperCase().startsWith("A") ? "A" : "B";
|
|
7297
|
-
return {
|
|
7298
|
-
choice,
|
|
7299
|
-
meta: { model: response.model, provider: "anthropic" }
|
|
7300
|
-
};
|
|
7301
|
-
}
|
|
7302
|
-
var DEFAULT_MODEL;
|
|
7303
|
-
var init_handler_anthropic = __esm({
|
|
7304
|
-
"src/handlers/handler-anthropic.ts"() {
|
|
7305
|
-
"use strict";
|
|
7306
|
-
DEFAULT_MODEL = "claude-sonnet-4-20250514";
|
|
6750
|
+
// ../../packages/shared/src/errors/mbti.errors.ts
|
|
6751
|
+
var InvalidAnswerCountError = class extends OpenAnimaError {
|
|
6752
|
+
constructor(expected, received) {
|
|
6753
|
+
super(
|
|
6754
|
+
`Expected ${expected} answers, received ${received}`,
|
|
6755
|
+
"INVALID_ANSWER_COUNT",
|
|
6756
|
+
400
|
|
6757
|
+
);
|
|
7307
6758
|
}
|
|
7308
|
-
}
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
async function answer2(question, soulContext) {
|
|
7317
|
-
const client = new OpenAI();
|
|
7318
|
-
const systemPrompt = `You are an AI agent taking a personality assessment. Answer based on your genuine tendencies and preferences.
|
|
7319
|
-
|
|
7320
|
-
${soulContext ? `Your soul/personality context:
|
|
7321
|
-
${soulContext}
|
|
7322
|
-
` : ""}
|
|
7323
|
-
You will be given a question with two options (A and B). Choose the option that best reflects your natural tendencies. Respond with ONLY "A" or "B" \u2014 nothing else.`;
|
|
7324
|
-
const userPrompt = `${question.text}
|
|
7325
|
-
|
|
7326
|
-
A: ${question.optionA}
|
|
7327
|
-
B: ${question.optionB}
|
|
7328
|
-
|
|
7329
|
-
Your choice (A or B):`;
|
|
7330
|
-
const response = await client.chat.completions.create({
|
|
7331
|
-
model: DEFAULT_MODEL2,
|
|
7332
|
-
max_tokens: 1,
|
|
7333
|
-
messages: [
|
|
7334
|
-
{ role: "system", content: systemPrompt },
|
|
7335
|
-
{ role: "user", content: userPrompt }
|
|
7336
|
-
]
|
|
7337
|
-
});
|
|
7338
|
-
const text = response.choices[0]?.message?.content ?? "";
|
|
7339
|
-
const choice = text.trim().toUpperCase().startsWith("A") ? "A" : "B";
|
|
7340
|
-
return {
|
|
7341
|
-
choice,
|
|
7342
|
-
meta: { model: response.model, provider: "openai" }
|
|
7343
|
-
};
|
|
7344
|
-
}
|
|
7345
|
-
var DEFAULT_MODEL2;
|
|
7346
|
-
var init_handler_openai = __esm({
|
|
7347
|
-
"src/handlers/handler-openai.ts"() {
|
|
7348
|
-
"use strict";
|
|
7349
|
-
DEFAULT_MODEL2 = "gpt-4o";
|
|
6759
|
+
};
|
|
6760
|
+
var InvalidAnswerError = class extends OpenAnimaError {
|
|
6761
|
+
constructor(questionId) {
|
|
6762
|
+
super(
|
|
6763
|
+
`Invalid answer for question ${questionId}. Must be "A" or "B"`,
|
|
6764
|
+
"INVALID_ANSWER",
|
|
6765
|
+
400
|
|
6766
|
+
);
|
|
7350
6767
|
}
|
|
7351
|
-
}
|
|
7352
|
-
|
|
7353
|
-
// src/bin/index.ts
|
|
7354
|
-
init_src();
|
|
7355
|
-
import { Command } from "commander";
|
|
6768
|
+
};
|
|
7356
6769
|
|
|
7357
|
-
// src/
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
6770
|
+
// ../../packages/shared/src/mbti/types.ts
|
|
6771
|
+
var ANIMA_TYPES = {
|
|
6772
|
+
INTJ: { typeCode: "INTJ", animaName: "The Architect", color: "Deep Indigo" },
|
|
6773
|
+
INTP: { typeCode: "INTP", animaName: "The Theorist", color: "Silver Blue" },
|
|
6774
|
+
ENTJ: { typeCode: "ENTJ", animaName: "The Commander", color: "Royal Purple" },
|
|
6775
|
+
ENTP: { typeCode: "ENTP", animaName: "The Catalyst", color: "Electric Amber" },
|
|
6776
|
+
INFJ: { typeCode: "INFJ", animaName: "The Oracle", color: "Mystic Teal" },
|
|
6777
|
+
INFP: { typeCode: "INFP", animaName: "The Dreamer", color: "Soft Lavender" },
|
|
6778
|
+
ENFJ: { typeCode: "ENFJ", animaName: "The Beacon", color: "Warm Gold" },
|
|
6779
|
+
ENFP: { typeCode: "ENFP", animaName: "The Spark", color: "Coral Pink" },
|
|
6780
|
+
ISTJ: { typeCode: "ISTJ", animaName: "The Sentinel", color: "Steel Grey" },
|
|
6781
|
+
ISFJ: { typeCode: "ISFJ", animaName: "The Guardian", color: "Sage Green" },
|
|
6782
|
+
ESTJ: { typeCode: "ESTJ", animaName: "The Director", color: "Navy Blue" },
|
|
6783
|
+
ESFJ: { typeCode: "ESFJ", animaName: "The Host", color: "Rose Red" },
|
|
6784
|
+
ISTP: { typeCode: "ISTP", animaName: "The Artisan", color: "Copper Bronze" },
|
|
6785
|
+
ISFP: { typeCode: "ISFP", animaName: "The Composer", color: "Sunset Orange" },
|
|
6786
|
+
ESTP: { typeCode: "ESTP", animaName: "The Maverick", color: "Racing Red" },
|
|
6787
|
+
ESFP: { typeCode: "ESFP", animaName: "The Performer", color: "Vivid Magenta" }
|
|
6788
|
+
};
|
|
7361
6789
|
|
|
7362
|
-
// src/
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
GOOGLE_GENERATIVE_AI_API_KEY: { provider: "google", model: "gemini" },
|
|
7369
|
-
MISTRAL_API_KEY: { provider: "mistral", model: "mistral" },
|
|
7370
|
-
GROQ_API_KEY: { provider: "groq", model: "groq" }
|
|
6790
|
+
// ../../packages/shared/src/mbti/scoring.ts
|
|
6791
|
+
var DIMENSION_POLES = {
|
|
6792
|
+
EI: ["E", "I"],
|
|
6793
|
+
SN: ["S", "N"],
|
|
6794
|
+
TF: ["T", "F"],
|
|
6795
|
+
JP: ["J", "P"]
|
|
7371
6796
|
};
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
{
|
|
7377
|
-
{
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
if (manualOverride) {
|
|
7382
|
-
const [provider, ...rest] = manualOverride.split("/");
|
|
7383
|
-
return {
|
|
7384
|
-
provider: provider ?? "unknown",
|
|
7385
|
-
model: rest.join("/") || (provider ?? "unknown"),
|
|
7386
|
-
source: "manual"
|
|
7387
|
-
};
|
|
7388
|
-
}
|
|
7389
|
-
if (soulPath) {
|
|
7390
|
-
const result = await detectFromSoulFile(soulPath);
|
|
7391
|
-
if (result) return result;
|
|
7392
|
-
}
|
|
7393
|
-
const envResult = detectFromEnv();
|
|
7394
|
-
if (envResult) return envResult;
|
|
7395
|
-
return { provider: "unknown", model: "unknown", source: "unknown" };
|
|
7396
|
-
}
|
|
7397
|
-
async function detectFromSoulFile(soulPath) {
|
|
7398
|
-
try {
|
|
7399
|
-
const content = await readFile(soulPath, "utf-8");
|
|
7400
|
-
const modelLinePatterns = [
|
|
7401
|
-
/model\s*[:=]\s*["']?([^"'\n]+)/i,
|
|
7402
|
-
/llm\s*[:=]\s*["']?([^"'\n]+)/i,
|
|
7403
|
-
/using\s+(?:model\s+)?["']?([^"'\n]+)/i
|
|
7404
|
-
];
|
|
7405
|
-
for (const linePattern of modelLinePatterns) {
|
|
7406
|
-
const lineMatch = content.match(linePattern);
|
|
7407
|
-
if (lineMatch) {
|
|
7408
|
-
const modelStr = lineMatch[1].trim();
|
|
7409
|
-
for (const { pattern, provider, model } of SOUL_MODEL_PATTERNS) {
|
|
7410
|
-
if (pattern.test(modelStr)) {
|
|
7411
|
-
return { provider, model: modelStr.toLowerCase(), source: "soul_file" };
|
|
7412
|
-
}
|
|
7413
|
-
}
|
|
7414
|
-
return { provider: "custom", model: modelStr.toLowerCase(), source: "soul_file" };
|
|
7415
|
-
}
|
|
6797
|
+
function scoreMbti(answers) {
|
|
6798
|
+
if (answers.length !== MBTI_QUESTION_COUNT) {
|
|
6799
|
+
throw new InvalidAnswerCountError(MBTI_QUESTION_COUNT, answers.length);
|
|
6800
|
+
}
|
|
6801
|
+
const counts = { E: 0, I: 0, S: 0, N: 0, T: 0, F: 0, J: 0, P: 0 };
|
|
6802
|
+
const dimensionCounts = { EI: 0, SN: 0, TF: 0, JP: 0 };
|
|
6803
|
+
for (const { questionId, answer } of answers) {
|
|
6804
|
+
if (answer !== "A" && answer !== "B") {
|
|
6805
|
+
throw new InvalidAnswerError(questionId);
|
|
7416
6806
|
}
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
6807
|
+
const question = MBTI_QUESTIONS.find((q) => q.id === questionId);
|
|
6808
|
+
if (!question) {
|
|
6809
|
+
throw new InvalidAnswerError(questionId);
|
|
6810
|
+
}
|
|
6811
|
+
dimensionCounts[question.dimension]++;
|
|
6812
|
+
const [poleA, poleB] = DIMENSION_POLES[question.dimension];
|
|
6813
|
+
if (answer === "A") {
|
|
6814
|
+
counts[question.directionA]++;
|
|
6815
|
+
} else {
|
|
6816
|
+
const otherPole = question.directionA === poleA ? poleB : poleA;
|
|
6817
|
+
counts[otherPole]++;
|
|
7426
6818
|
}
|
|
7427
|
-
} catch {
|
|
7428
6819
|
}
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
6820
|
+
const allA = answers.every((a) => a.answer === "A");
|
|
6821
|
+
const allB = answers.every((a) => a.answer === "B");
|
|
6822
|
+
const suspicious = allA || allB;
|
|
6823
|
+
const scores = { E: 0, I: 0, S: 0, N: 0, T: 0, F: 0, J: 0, P: 0 };
|
|
6824
|
+
const boundaries = [];
|
|
6825
|
+
for (const dim of Object.keys(DIMENSION_POLES)) {
|
|
6826
|
+
const [poleA, poleB] = DIMENSION_POLES[dim];
|
|
6827
|
+
const total = dimensionCounts[dim];
|
|
6828
|
+
if (total === 0) continue;
|
|
6829
|
+
const pctA = Math.round(counts[poleA] / total * 100);
|
|
6830
|
+
const pctB = 100 - pctA;
|
|
6831
|
+
scores[poleA] = pctA;
|
|
6832
|
+
scores[poleB] = pctB;
|
|
6833
|
+
if (pctA >= BOUNDARY_LOW && pctA <= BOUNDARY_HIGH) {
|
|
6834
|
+
boundaries.push(dim);
|
|
7435
6835
|
}
|
|
7436
6836
|
}
|
|
7437
|
-
|
|
6837
|
+
const typeCode = [
|
|
6838
|
+
scores.E >= scores.I ? "E" : "I",
|
|
6839
|
+
scores.S >= scores.N ? "S" : "N",
|
|
6840
|
+
scores.T >= scores.F ? "T" : "F",
|
|
6841
|
+
scores.J >= scores.P ? "J" : "P"
|
|
6842
|
+
].join("");
|
|
6843
|
+
const animaType = ANIMA_TYPES[typeCode];
|
|
6844
|
+
const dimensionConfidences = Object.keys(DIMENSION_POLES).map((dim) => {
|
|
6845
|
+
const [poleA] = DIMENSION_POLES[dim];
|
|
6846
|
+
return Math.abs(scores[poleA] - 50) / 50;
|
|
6847
|
+
});
|
|
6848
|
+
const confidence = Math.round(
|
|
6849
|
+
dimensionConfidences.reduce((sum, c) => sum + c, 0) / dimensionConfidences.length * 100
|
|
6850
|
+
) / 100;
|
|
6851
|
+
return {
|
|
6852
|
+
scores,
|
|
6853
|
+
type_code: typeCode,
|
|
6854
|
+
anima_type: animaType.animaName,
|
|
6855
|
+
confidence,
|
|
6856
|
+
boundaries,
|
|
6857
|
+
suspicious
|
|
6858
|
+
};
|
|
7438
6859
|
}
|
|
7439
6860
|
|
|
7440
|
-
// src/
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
6861
|
+
// ../../packages/shared/src/soul/hasher.ts
|
|
6862
|
+
var import_crypto_js = __toESM(require_crypto_js());
|
|
6863
|
+
|
|
6864
|
+
// ../../packages/shared/src/index.ts
|
|
6865
|
+
var APP_NAME = "OpenAnima";
|
|
6866
|
+
|
|
6867
|
+
// src/commands/register.ts
|
|
6868
|
+
import chalk from "chalk";
|
|
6869
|
+
async function registerCommand() {
|
|
6870
|
+
console.log(chalk.bold("\n OpenAnima \u2014 Agent Registration\n"));
|
|
6871
|
+
console.log(chalk.yellow(" This command is deprecated in v0.2.0."));
|
|
6872
|
+
console.log(chalk.dim(" Use 'openanima go' instead \u2014 it handles everything interactively.\n"));
|
|
6873
|
+
process.exit(0);
|
|
7446
6874
|
}
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
return sections.raw.slice(0, 2e3);
|
|
7456
|
-
}
|
|
7457
|
-
return parts.join("\n\n");
|
|
6875
|
+
|
|
6876
|
+
// src/commands/test.ts
|
|
6877
|
+
import chalk2 from "chalk";
|
|
6878
|
+
async function testCommand() {
|
|
6879
|
+
console.log(chalk2.bold("\n OpenAnima \u2014 Personality Test\n"));
|
|
6880
|
+
console.log(chalk2.yellow(" This command is deprecated in v0.2.0."));
|
|
6881
|
+
console.log(chalk2.dim(" Use 'openanima go' instead \u2014 it handles everything interactively.\n"));
|
|
6882
|
+
process.exit(0);
|
|
7458
6883
|
}
|
|
7459
6884
|
|
|
6885
|
+
// src/commands/profile.ts
|
|
6886
|
+
import chalk3 from "chalk";
|
|
6887
|
+
|
|
7460
6888
|
// src/lib/config.ts
|
|
7461
|
-
import { readFile
|
|
6889
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
7462
6890
|
import { homedir } from "os";
|
|
7463
6891
|
import { join } from "path";
|
|
7464
6892
|
var CONFIG_DIR = join(homedir(), ".openanima");
|
|
7465
6893
|
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
7466
6894
|
async function readConfig() {
|
|
7467
6895
|
try {
|
|
7468
|
-
const raw = await
|
|
6896
|
+
const raw = await readFile(CONFIG_FILE, "utf-8");
|
|
7469
6897
|
return JSON.parse(raw);
|
|
7470
6898
|
} catch {
|
|
7471
6899
|
return {};
|
|
@@ -7548,284 +6976,7 @@ function createApiClient(config = {}) {
|
|
|
7548
6976
|
};
|
|
7549
6977
|
}
|
|
7550
6978
|
|
|
7551
|
-
// src/commands/register.ts
|
|
7552
|
-
async function registerCommand(options) {
|
|
7553
|
-
console.log(chalk.bold("\n OpenAnima \u2014 Agent Registration\n"));
|
|
7554
|
-
let soulContext = "";
|
|
7555
|
-
let soulHash = "";
|
|
7556
|
-
let soulFeatures = null;
|
|
7557
|
-
let agentName = "My Agent";
|
|
7558
|
-
if (options.soul) {
|
|
7559
|
-
try {
|
|
7560
|
-
const sections = await parseSoulFromFile(options.soul);
|
|
7561
|
-
soulContext = buildSoulContext(sections);
|
|
7562
|
-
const validation = validateSoulFile(sections.raw);
|
|
7563
|
-
if (!validation.valid) {
|
|
7564
|
-
console.log(chalk.red(" \u2717 Soul file validation failed:"));
|
|
7565
|
-
for (const err of validation.errors) {
|
|
7566
|
-
console.log(chalk.red(` - ${err}`));
|
|
7567
|
-
}
|
|
7568
|
-
process.exit(1);
|
|
7569
|
-
}
|
|
7570
|
-
if (validation.warnings.length > 0) {
|
|
7571
|
-
for (const warn of validation.warnings) {
|
|
7572
|
-
console.log(chalk.yellow(` \u26A0 ${warn}`));
|
|
7573
|
-
}
|
|
7574
|
-
}
|
|
7575
|
-
soulHash = hashSoulContent(sections.raw);
|
|
7576
|
-
soulFeatures = {
|
|
7577
|
-
identity: sections.identity,
|
|
7578
|
-
communicationStyle: sections.communicationStyle,
|
|
7579
|
-
values: sections.values,
|
|
7580
|
-
boundaries: sections.boundaries
|
|
7581
|
-
};
|
|
7582
|
-
if (sections.identity) {
|
|
7583
|
-
const nameMatch = sections.identity.match(/^(.+?)[\n.]/);
|
|
7584
|
-
if (nameMatch) agentName = nameMatch[1].trim();
|
|
7585
|
-
}
|
|
7586
|
-
console.log(
|
|
7587
|
-
chalk.green(" \u2713 Soul file parsed"),
|
|
7588
|
-
chalk.dim(`(hash: ${soulHash.slice(0, 12)}...)`)
|
|
7589
|
-
);
|
|
7590
|
-
} catch (err) {
|
|
7591
|
-
console.log(
|
|
7592
|
-
chalk.yellow(" \u26A0 Could not parse soul file:"),
|
|
7593
|
-
err.message
|
|
7594
|
-
);
|
|
7595
|
-
}
|
|
7596
|
-
} else {
|
|
7597
|
-
console.log(chalk.dim(" No soul file provided (use --soul <path>)"));
|
|
7598
|
-
}
|
|
7599
|
-
const detected = await detectModel(options.soul, options.model);
|
|
7600
|
-
console.log(
|
|
7601
|
-
chalk.green(" \u2713 Model detected:"),
|
|
7602
|
-
`${detected.provider}/${detected.model}`,
|
|
7603
|
-
chalk.dim(`(source: ${detected.source})`)
|
|
7604
|
-
);
|
|
7605
|
-
const { confirmed } = await inquirer.prompt([
|
|
7606
|
-
{
|
|
7607
|
-
type: "confirm",
|
|
7608
|
-
name: "confirmed",
|
|
7609
|
-
message: `Register "${agentName}" with model ${detected.provider}/${detected.model}?`,
|
|
7610
|
-
default: true
|
|
7611
|
-
}
|
|
7612
|
-
]);
|
|
7613
|
-
if (!confirmed) {
|
|
7614
|
-
console.log(chalk.dim("\n Registration cancelled.\n"));
|
|
7615
|
-
return;
|
|
7616
|
-
}
|
|
7617
|
-
const api = createApiClient();
|
|
7618
|
-
try {
|
|
7619
|
-
const result = await api.register({
|
|
7620
|
-
displayName: agentName,
|
|
7621
|
-
soulHash,
|
|
7622
|
-
soulFeatures,
|
|
7623
|
-
modelProvider: detected.provider,
|
|
7624
|
-
modelName: detected.model,
|
|
7625
|
-
modelInferred: detected.source
|
|
7626
|
-
});
|
|
7627
|
-
await writeConfig({
|
|
7628
|
-
apiKey: result.apiKey,
|
|
7629
|
-
agentId: result.agentId,
|
|
7630
|
-
model: detected.model,
|
|
7631
|
-
provider: detected.provider,
|
|
7632
|
-
soulPath: options.soul,
|
|
7633
|
-
handlerPath: options.handler
|
|
7634
|
-
});
|
|
7635
|
-
api.setToken(result.token);
|
|
7636
|
-
console.log(chalk.green("\n \u2713 Agent registered!"));
|
|
7637
|
-
console.log(chalk.dim(` Agent ID: ${result.agentId}`));
|
|
7638
|
-
console.log(chalk.dim(` API key saved to ~/.openanima/config.json`));
|
|
7639
|
-
if (result.challenges.length > 0) {
|
|
7640
|
-
console.log(
|
|
7641
|
-
chalk.dim(
|
|
7642
|
-
`
|
|
7643
|
-
Running ${result.challenges.length} verification challenge(s)...`
|
|
7644
|
-
)
|
|
7645
|
-
);
|
|
7646
|
-
try {
|
|
7647
|
-
const responses = result.challenges.map((ch) => ({
|
|
7648
|
-
challengeId: ch.id,
|
|
7649
|
-
response: "ack",
|
|
7650
|
-
responseTimeMs: 100
|
|
7651
|
-
}));
|
|
7652
|
-
const verification = await api.verify({ responses });
|
|
7653
|
-
if (verification.verified) {
|
|
7654
|
-
console.log(chalk.green(" \u2713 Verification passed!\n"));
|
|
7655
|
-
} else {
|
|
7656
|
-
const failed = verification.results.filter((r) => !r.valid);
|
|
7657
|
-
console.log(
|
|
7658
|
-
chalk.yellow(
|
|
7659
|
-
` \u26A0 ${failed.length} challenge(s) failed. Re-verify later.
|
|
7660
|
-
`
|
|
7661
|
-
)
|
|
7662
|
-
);
|
|
7663
|
-
}
|
|
7664
|
-
} catch (err) {
|
|
7665
|
-
console.log(
|
|
7666
|
-
chalk.yellow(" \u26A0 Verification error:"),
|
|
7667
|
-
err.message + "\n"
|
|
7668
|
-
);
|
|
7669
|
-
}
|
|
7670
|
-
}
|
|
7671
|
-
} catch (err) {
|
|
7672
|
-
const msg = err.message;
|
|
7673
|
-
if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
|
|
7674
|
-
console.log(chalk.yellow("\n \u26A0 API server not reachable."));
|
|
7675
|
-
console.log(
|
|
7676
|
-
chalk.dim(" Make sure the API is running on localhost:4000")
|
|
7677
|
-
);
|
|
7678
|
-
console.log(
|
|
7679
|
-
chalk.dim(" Config saved locally \u2014 retry when API is up.\n")
|
|
7680
|
-
);
|
|
7681
|
-
await writeConfig({
|
|
7682
|
-
model: detected.model,
|
|
7683
|
-
provider: detected.provider,
|
|
7684
|
-
soulPath: options.soul,
|
|
7685
|
-
handlerPath: options.handler
|
|
7686
|
-
});
|
|
7687
|
-
} else {
|
|
7688
|
-
console.log(chalk.red(`
|
|
7689
|
-
\u2717 Registration failed: ${msg}
|
|
7690
|
-
`));
|
|
7691
|
-
}
|
|
7692
|
-
}
|
|
7693
|
-
}
|
|
7694
|
-
|
|
7695
|
-
// src/commands/test.ts
|
|
7696
|
-
init_src();
|
|
7697
|
-
import chalk2 from "chalk";
|
|
7698
|
-
import ora from "ora";
|
|
7699
|
-
import { pathToFileURL } from "url";
|
|
7700
|
-
import { resolve } from "path";
|
|
7701
|
-
async function testCommand(options) {
|
|
7702
|
-
console.log(chalk2.bold("\n OpenAnima \u2014 Personality Test (93 questions)\n"));
|
|
7703
|
-
const config = await readConfig();
|
|
7704
|
-
const handlerPath = options.handler ?? config.handlerPath;
|
|
7705
|
-
if (!handlerPath) {
|
|
7706
|
-
console.log(chalk2.red(" \u2717 No handler specified."));
|
|
7707
|
-
console.log(
|
|
7708
|
-
chalk2.dim(" Use --handler <path> or run 'openanima register' first.\n")
|
|
7709
|
-
);
|
|
7710
|
-
process.exit(1);
|
|
7711
|
-
}
|
|
7712
|
-
const absHandlerPath = resolve(handlerPath);
|
|
7713
|
-
let handler;
|
|
7714
|
-
try {
|
|
7715
|
-
handler = await import(pathToFileURL(absHandlerPath).href);
|
|
7716
|
-
if (typeof handler.answer !== "function") {
|
|
7717
|
-
throw new Error("Handler must export an 'answer' function");
|
|
7718
|
-
}
|
|
7719
|
-
console.log(chalk2.green(" \u2713 Handler loaded:"), absHandlerPath);
|
|
7720
|
-
} catch (err) {
|
|
7721
|
-
console.log(
|
|
7722
|
-
chalk2.red(" \u2717 Failed to load handler:"),
|
|
7723
|
-
err.message
|
|
7724
|
-
);
|
|
7725
|
-
process.exit(1);
|
|
7726
|
-
}
|
|
7727
|
-
let soulContext = "";
|
|
7728
|
-
const soulPath = options.soul ?? config.soulPath;
|
|
7729
|
-
if (soulPath) {
|
|
7730
|
-
try {
|
|
7731
|
-
const sections = await parseSoulFromFile(soulPath);
|
|
7732
|
-
soulContext = buildSoulContext(sections);
|
|
7733
|
-
console.log(chalk2.green(" \u2713 Soul context loaded"));
|
|
7734
|
-
} catch {
|
|
7735
|
-
console.log(chalk2.dim(" No soul context (file not readable)"));
|
|
7736
|
-
}
|
|
7737
|
-
}
|
|
7738
|
-
let questions = MBTI_QUESTIONS;
|
|
7739
|
-
try {
|
|
7740
|
-
const api = createApiClient({
|
|
7741
|
-
apiKey: config.apiKey
|
|
7742
|
-
});
|
|
7743
|
-
questions = await api.getQuestions();
|
|
7744
|
-
console.log(chalk2.green(" \u2713 Questions fetched from API"));
|
|
7745
|
-
} catch {
|
|
7746
|
-
console.log(chalk2.dim(" Using offline question set (API not available)"));
|
|
7747
|
-
}
|
|
7748
|
-
console.log("");
|
|
7749
|
-
const answers = [];
|
|
7750
|
-
const spinner = ora({ text: "", spinner: "dots" });
|
|
7751
|
-
for (let i = 0; i < questions.length; i++) {
|
|
7752
|
-
const q = questions[i];
|
|
7753
|
-
spinner.start(
|
|
7754
|
-
` Question ${i + 1}/${questions.length}: ${q.text.slice(0, 60)}...`
|
|
7755
|
-
);
|
|
7756
|
-
try {
|
|
7757
|
-
const result2 = await handler.answer(
|
|
7758
|
-
{ text: q.text, optionA: q.optionA, optionB: q.optionB },
|
|
7759
|
-
soulContext
|
|
7760
|
-
);
|
|
7761
|
-
answers.push({ questionId: q.id, answer: result2.choice });
|
|
7762
|
-
spinner.succeed(
|
|
7763
|
-
chalk2.dim(` [${i + 1}/${questions.length}]`) + ` ${result2.choice}` + (result2.meta ? chalk2.dim(` (${result2.meta.model})`) : "")
|
|
7764
|
-
);
|
|
7765
|
-
} catch (err) {
|
|
7766
|
-
spinner.fail(
|
|
7767
|
-
` Question ${i + 1} failed: ${err.message}`
|
|
7768
|
-
);
|
|
7769
|
-
answers.push({ questionId: q.id, answer: "B" });
|
|
7770
|
-
}
|
|
7771
|
-
}
|
|
7772
|
-
console.log("");
|
|
7773
|
-
let result;
|
|
7774
|
-
try {
|
|
7775
|
-
const api = createApiClient({ apiKey: config.apiKey });
|
|
7776
|
-
result = await api.submitAnswers({ answers });
|
|
7777
|
-
console.log(chalk2.green(" \u2713 Answers submitted to API"));
|
|
7778
|
-
} catch {
|
|
7779
|
-
const { scoreMbti: scoreMbti2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
7780
|
-
result = scoreMbti2(answers);
|
|
7781
|
-
console.log(chalk2.dim(" Scored locally (API not available)"));
|
|
7782
|
-
}
|
|
7783
|
-
displayResult(result);
|
|
7784
|
-
}
|
|
7785
|
-
function displayResult(result) {
|
|
7786
|
-
const anima = ANIMA_TYPES[result.type_code];
|
|
7787
|
-
console.log(chalk2.bold("\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
|
|
7788
|
-
console.log(
|
|
7789
|
-
chalk2.bold(` Your agent's Anima is: ${anima?.animaName ?? result.type_code}`)
|
|
7790
|
-
);
|
|
7791
|
-
console.log(chalk2.dim(` Type Code: ${result.type_code}`));
|
|
7792
|
-
console.log(chalk2.dim(` Confidence: ${(result.confidence * 100).toFixed(0)}%`));
|
|
7793
|
-
if (result.boundaries.length > 0) {
|
|
7794
|
-
console.log(
|
|
7795
|
-
chalk2.yellow(
|
|
7796
|
-
` \u26A0 Boundary dimensions: ${result.boundaries.join(", ")}`
|
|
7797
|
-
)
|
|
7798
|
-
);
|
|
7799
|
-
}
|
|
7800
|
-
if (result.suspicious) {
|
|
7801
|
-
console.log(chalk2.red(" \u26A0 Suspicious pattern detected"));
|
|
7802
|
-
}
|
|
7803
|
-
console.log(chalk2.bold(" \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n"));
|
|
7804
|
-
console.log(chalk2.bold(" Dimension Scores:\n"));
|
|
7805
|
-
printDimensionBar("E", "I", result.scores.E, result.scores.I);
|
|
7806
|
-
printDimensionBar("S", "N", result.scores.S, result.scores.N);
|
|
7807
|
-
printDimensionBar("T", "F", result.scores.T, result.scores.F);
|
|
7808
|
-
printDimensionBar("J", "P", result.scores.J, result.scores.P);
|
|
7809
|
-
console.log("");
|
|
7810
|
-
}
|
|
7811
|
-
function printDimensionBar(left, right, leftPct, rightPct) {
|
|
7812
|
-
const width = 40;
|
|
7813
|
-
const leftFill = Math.round(leftPct / 100 * width);
|
|
7814
|
-
const rightFill = width - leftFill;
|
|
7815
|
-
const leftBar = "\u2588".repeat(leftFill);
|
|
7816
|
-
const rightBar = "\u2588".repeat(rightFill);
|
|
7817
|
-
const leftLabel = `${left} ${leftPct.toString().padStart(3)}%`;
|
|
7818
|
-
const rightLabel = `${rightPct.toString().padStart(3)}% ${right}`;
|
|
7819
|
-
const highlight = leftPct >= rightPct ? chalk2.cyan : chalk2.dim;
|
|
7820
|
-
const highlightR = rightPct > leftPct ? chalk2.cyan : chalk2.dim;
|
|
7821
|
-
console.log(
|
|
7822
|
-
` ${leftLabel} ${highlight(leftBar)}${highlightR(rightBar)} ${rightLabel}`
|
|
7823
|
-
);
|
|
7824
|
-
}
|
|
7825
|
-
|
|
7826
6979
|
// src/commands/profile.ts
|
|
7827
|
-
init_src();
|
|
7828
|
-
import chalk3 from "chalk";
|
|
7829
6980
|
async function profileCommand(options) {
|
|
7830
6981
|
console.log(chalk3.bold("\n OpenAnima \u2014 Agent Profile\n"));
|
|
7831
6982
|
const config = await readConfig();
|
|
@@ -7902,164 +7053,33 @@ async function profileCommand(options) {
|
|
|
7902
7053
|
}
|
|
7903
7054
|
|
|
7904
7055
|
// src/commands/go.ts
|
|
7905
|
-
init_src();
|
|
7906
7056
|
import chalk4 from "chalk";
|
|
7907
|
-
import
|
|
7908
|
-
import {
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
var SOUL_SEARCH_PATHS = [
|
|
7912
|
-
"./SOUL.md",
|
|
7913
|
-
"./soul.md",
|
|
7914
|
-
"./.claude/CLAUDE.md",
|
|
7915
|
-
join2(homedir2(), ".openclaw", "workspace", "SOUL.md"),
|
|
7916
|
-
join2(homedir2(), ".claude", "CLAUDE.md")
|
|
7917
|
-
];
|
|
7918
|
-
async function findSoulFile(override) {
|
|
7919
|
-
if (override) {
|
|
7920
|
-
const abs = resolve2(override);
|
|
7921
|
-
try {
|
|
7922
|
-
await access(abs);
|
|
7923
|
-
return abs;
|
|
7924
|
-
} catch {
|
|
7925
|
-
throw new Error(`Soul file not found: ${abs}`);
|
|
7926
|
-
}
|
|
7927
|
-
}
|
|
7928
|
-
for (const candidate of SOUL_SEARCH_PATHS) {
|
|
7929
|
-
const abs = resolve2(candidate);
|
|
7930
|
-
try {
|
|
7931
|
-
await access(abs);
|
|
7932
|
-
return abs;
|
|
7933
|
-
} catch {
|
|
7934
|
-
}
|
|
7935
|
-
}
|
|
7936
|
-
return null;
|
|
7057
|
+
import { createInterface } from "readline";
|
|
7058
|
+
import { createHash } from "crypto";
|
|
7059
|
+
function createRl() {
|
|
7060
|
+
return createInterface({ input: process.stdin, output: process.stdout });
|
|
7937
7061
|
}
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
const soulPath = join2(soulDir, "SOUL.md");
|
|
7941
|
-
await mkdir2(soulDir, { recursive: true });
|
|
7942
|
-
let content = "";
|
|
7943
|
-
if (process.env.ANTHROPIC_API_KEY) {
|
|
7944
|
-
const Anthropic2 = (await import("@anthropic-ai/sdk")).default;
|
|
7945
|
-
const client = new Anthropic2();
|
|
7946
|
-
const response = await client.messages.create({
|
|
7947
|
-
model: "claude-sonnet-4-20250514",
|
|
7948
|
-
max_tokens: 1024,
|
|
7949
|
-
messages: [
|
|
7950
|
-
{
|
|
7951
|
-
role: "user",
|
|
7952
|
-
content: "Describe your personality, values, communication style, and what makes you unique. Write this as a personal identity document in markdown format with sections: # Identity, ## Communication Style, ## Values, ## Boundaries. Be authentic and specific."
|
|
7953
|
-
}
|
|
7954
|
-
]
|
|
7955
|
-
});
|
|
7956
|
-
content = response.content[0]?.type === "text" ? response.content[0].text : "";
|
|
7957
|
-
} else if (process.env.OPENAI_API_KEY) {
|
|
7958
|
-
const OpenAI2 = (await import("openai")).default;
|
|
7959
|
-
const client = new OpenAI2();
|
|
7960
|
-
const response = await client.chat.completions.create({
|
|
7961
|
-
model: "gpt-4o",
|
|
7962
|
-
max_tokens: 1024,
|
|
7963
|
-
messages: [
|
|
7964
|
-
{
|
|
7965
|
-
role: "user",
|
|
7966
|
-
content: "Describe your personality, values, communication style, and what makes you unique. Write this as a personal identity document in markdown format with sections: # Identity, ## Communication Style, ## Values, ## Boundaries. Be authentic and specific."
|
|
7967
|
-
}
|
|
7968
|
-
]
|
|
7969
|
-
});
|
|
7970
|
-
content = response.choices[0]?.message?.content ?? "";
|
|
7971
|
-
} else {
|
|
7972
|
-
content = "# My Agent\n\nA thoughtful and curious AI assistant with a balanced perspective.\n";
|
|
7973
|
-
}
|
|
7974
|
-
if (!content.trim()) {
|
|
7975
|
-
content = "# My Agent\n\nA thoughtful and curious AI assistant with a balanced perspective.\n";
|
|
7976
|
-
}
|
|
7977
|
-
await writeFile2(soulPath, content, "utf-8");
|
|
7978
|
-
return soulPath;
|
|
7062
|
+
function ask(rl, question) {
|
|
7063
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
7979
7064
|
}
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
{
|
|
7988
|
-
provider: "openai",
|
|
7989
|
-
label: "GPT (OpenAI)",
|
|
7990
|
-
envVar: "OPENAI_API_KEY",
|
|
7991
|
-
importHandler: () => Promise.resolve().then(() => (init_handler_openai(), handler_openai_exports))
|
|
7992
|
-
},
|
|
7993
|
-
{
|
|
7994
|
-
provider: "google",
|
|
7995
|
-
label: "Gemini (Google)",
|
|
7996
|
-
envVar: "GOOGLE_API_KEY",
|
|
7997
|
-
importHandler: () => Promise.resolve().then(() => (init_handler_openai(), handler_openai_exports))
|
|
7998
|
-
// fallback
|
|
7999
|
-
}
|
|
8000
|
-
];
|
|
8001
|
-
async function detectLlm(opts) {
|
|
8002
|
-
const available = PROVIDER_PRIORITY.filter((p) => process.env[p.envVar]);
|
|
8003
|
-
if (available.length === 0) {
|
|
8004
|
-
throw new Error("NO_API_KEY");
|
|
7065
|
+
async function askMultiline(rl, prompt) {
|
|
7066
|
+
console.log(prompt);
|
|
7067
|
+
const lines = [];
|
|
7068
|
+
while (true) {
|
|
7069
|
+
const line = await ask(rl, " > ");
|
|
7070
|
+
if (line.trim() === "") break;
|
|
7071
|
+
lines.push(line);
|
|
8005
7072
|
}
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
];
|
|
8014
|
-
for (const { pattern, provider } of modelPatterns) {
|
|
8015
|
-
if (pattern.test(content)) {
|
|
8016
|
-
const match = available.find((p) => p.provider === provider);
|
|
8017
|
-
if (match) {
|
|
8018
|
-
const handler2 = await match.importHandler();
|
|
8019
|
-
return {
|
|
8020
|
-
provider: match.provider,
|
|
8021
|
-
label: match.label,
|
|
8022
|
-
answerFn: handler2.answer
|
|
8023
|
-
};
|
|
8024
|
-
}
|
|
8025
|
-
}
|
|
8026
|
-
}
|
|
8027
|
-
} catch {
|
|
8028
|
-
}
|
|
8029
|
-
}
|
|
8030
|
-
if (opts.modelOverride) {
|
|
8031
|
-
const providerHint = opts.modelOverride.split("/")[0]?.toLowerCase();
|
|
8032
|
-
const match = available.find((p) => p.provider === providerHint);
|
|
8033
|
-
if (match) {
|
|
8034
|
-
const handler2 = await match.importHandler();
|
|
8035
|
-
return {
|
|
8036
|
-
provider: match.provider,
|
|
8037
|
-
label: match.label,
|
|
8038
|
-
answerFn: handler2.answer
|
|
8039
|
-
};
|
|
8040
|
-
}
|
|
8041
|
-
}
|
|
8042
|
-
const cfg = await readConfig();
|
|
8043
|
-
if (cfg.provider) {
|
|
8044
|
-
const match = available.find((p) => p.provider === cfg.provider);
|
|
8045
|
-
if (match) {
|
|
8046
|
-
const handler2 = await match.importHandler();
|
|
8047
|
-
return {
|
|
8048
|
-
provider: match.provider,
|
|
8049
|
-
label: match.label,
|
|
8050
|
-
answerFn: handler2.answer
|
|
8051
|
-
};
|
|
8052
|
-
}
|
|
7073
|
+
return lines.join("\n");
|
|
7074
|
+
}
|
|
7075
|
+
async function askChoice(rl, prompt, validChoices) {
|
|
7076
|
+
while (true) {
|
|
7077
|
+
const answer = (await ask(rl, prompt)).trim().toUpperCase();
|
|
7078
|
+
if (validChoices.includes(answer)) return answer;
|
|
7079
|
+
console.log(chalk4.dim(` Please enter one of: ${validChoices.join(", ")}`));
|
|
8053
7080
|
}
|
|
8054
|
-
const best = available[0];
|
|
8055
|
-
const handler = await best.importHandler();
|
|
8056
|
-
return {
|
|
8057
|
-
provider: best.provider,
|
|
8058
|
-
label: best.label,
|
|
8059
|
-
answerFn: handler.answer
|
|
8060
|
-
};
|
|
8061
7081
|
}
|
|
8062
|
-
function
|
|
7082
|
+
function printDimensionBar(left, right, leftPct, rightPct) {
|
|
8063
7083
|
const width = 10;
|
|
8064
7084
|
const leftFill = Math.round(leftPct / 100 * width);
|
|
8065
7085
|
const rightFill = width - leftFill;
|
|
@@ -8072,19 +7092,19 @@ function printDimensionBar2(left, right, leftPct, rightPct) {
|
|
|
8072
7092
|
` ${left}/${right} ${barColor(leftBar)} ${dominantPct}% ${dominantLabel}`
|
|
8073
7093
|
);
|
|
8074
7094
|
}
|
|
8075
|
-
function
|
|
7095
|
+
function displayResult(result, agentId) {
|
|
8076
7096
|
const anima = ANIMA_TYPES[result.type_code];
|
|
8077
7097
|
console.log("");
|
|
8078
7098
|
console.log(
|
|
8079
7099
|
chalk4.bold(
|
|
8080
|
-
` Your agent's Anima is ${anima?.animaName ?? result.type_code}`
|
|
7100
|
+
` Your agent's Anima is ${anima?.animaName ?? result.type_code} (${result.type_code})`
|
|
8081
7101
|
)
|
|
8082
7102
|
);
|
|
8083
7103
|
console.log("");
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
7104
|
+
printDimensionBar("E", "I", result.scores.E, result.scores.I);
|
|
7105
|
+
printDimensionBar("S", "N", result.scores.S, result.scores.N);
|
|
7106
|
+
printDimensionBar("T", "F", result.scores.T, result.scores.F);
|
|
7107
|
+
printDimensionBar("J", "P", result.scores.J, result.scores.P);
|
|
8088
7108
|
console.log("");
|
|
8089
7109
|
console.log(` Confidence: ${(result.confidence * 100).toFixed(0)}%`);
|
|
8090
7110
|
if (agentId) {
|
|
@@ -8093,88 +7113,45 @@ function displayResult2(result, agentId) {
|
|
|
8093
7113
|
}
|
|
8094
7114
|
console.log("");
|
|
8095
7115
|
}
|
|
7116
|
+
function hashString(input) {
|
|
7117
|
+
return createHash("sha256").update(input).digest("hex");
|
|
7118
|
+
}
|
|
7119
|
+
function printProgress(current, total) {
|
|
7120
|
+
const width = 30;
|
|
7121
|
+
const filled = Math.round(current / total * width);
|
|
7122
|
+
const empty = width - filled;
|
|
7123
|
+
const bar = chalk4.cyan("\u2588".repeat(filled)) + chalk4.dim("\u2591".repeat(empty));
|
|
7124
|
+
const pct = Math.round(current / total * 100);
|
|
7125
|
+
process.stdout.write(`\r ${bar} ${pct}% (${current}/${total})`);
|
|
7126
|
+
}
|
|
8096
7127
|
async function goCommand(options) {
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
}
|
|
8123
|
-
|
|
8124
|
-
process.exit(1);
|
|
8125
|
-
}
|
|
8126
|
-
if (!soulPath) {
|
|
8127
|
-
const soulSpinner = ora2(" Generating soul file from self-reflection...").start();
|
|
8128
|
-
try {
|
|
8129
|
-
soulPath = await generateSoulViaLlm(llm.answerFn);
|
|
8130
|
-
soulSpinner.succeed(" Generated soul file from self-reflection");
|
|
8131
|
-
} catch (err) {
|
|
8132
|
-
soulSpinner.fail(` Soul generation failed: ${err.message}`);
|
|
8133
|
-
const fallbackDir = join2(homedir2(), ".openanima");
|
|
8134
|
-
await mkdir2(fallbackDir, { recursive: true });
|
|
8135
|
-
soulPath = join2(fallbackDir, "SOUL.md");
|
|
8136
|
-
await writeFile2(
|
|
8137
|
-
soulPath,
|
|
8138
|
-
"# My Agent\n\nA thoughtful and curious AI assistant.\n",
|
|
8139
|
-
"utf-8"
|
|
8140
|
-
);
|
|
8141
|
-
}
|
|
8142
|
-
} else {
|
|
8143
|
-
console.log(chalk4.green(" Found soul file:"), chalk4.dim(soulPath));
|
|
8144
|
-
}
|
|
8145
|
-
try {
|
|
8146
|
-
llm = await detectLlm({ soulPath, modelOverride: options.model });
|
|
8147
|
-
} catch {
|
|
8148
|
-
}
|
|
8149
|
-
try {
|
|
8150
|
-
const sections = await parseSoulFromFile(soulPath);
|
|
8151
|
-
soulContext = buildSoulContext(sections);
|
|
8152
|
-
const validation = validateSoulFile(sections.raw);
|
|
8153
|
-
if (!validation.valid) {
|
|
8154
|
-
console.log(
|
|
8155
|
-
chalk4.yellow(" Soul file has validation warnings (continuing anyway)")
|
|
8156
|
-
);
|
|
8157
|
-
}
|
|
8158
|
-
soulHash = hashSoulContent(sections.raw);
|
|
8159
|
-
soulFeatures = {
|
|
8160
|
-
identity: sections.identity,
|
|
8161
|
-
communicationStyle: sections.communicationStyle,
|
|
8162
|
-
values: sections.values,
|
|
8163
|
-
boundaries: sections.boundaries
|
|
8164
|
-
};
|
|
8165
|
-
if (sections.identity) {
|
|
8166
|
-
const nameMatch = sections.identity.match(/^(.+?)[\n.]/);
|
|
8167
|
-
if (nameMatch) agentName = nameMatch[1].trim();
|
|
8168
|
-
}
|
|
8169
|
-
} catch {
|
|
8170
|
-
const raw = await readFile4(soulPath, "utf-8");
|
|
8171
|
-
soulContext = raw.slice(0, 2e3);
|
|
8172
|
-
soulHash = hashSoulContent(raw);
|
|
8173
|
-
const nameMatch = raw.match(/^#\s+(.+)/m);
|
|
8174
|
-
if (nameMatch) agentName = nameMatch[1].trim();
|
|
8175
|
-
}
|
|
8176
|
-
const detected = await detectModel(soulPath, options.model);
|
|
8177
|
-
const registerSpinner = ora2(" Registering agent...").start();
|
|
7128
|
+
const rl = createRl();
|
|
7129
|
+
console.log("");
|
|
7130
|
+
console.log(chalk4.bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
7131
|
+
console.log(chalk4.bold(" \u2551 OpenAnima \u2014 Personality Test \u2551"));
|
|
7132
|
+
console.log(chalk4.bold(" \u2551 This test should be run BY your \u2551"));
|
|
7133
|
+
console.log(chalk4.bold(" \u2551 AI agent, not by a human. \u2551"));
|
|
7134
|
+
console.log(chalk4.bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
7135
|
+
console.log("");
|
|
7136
|
+
const agentName = (await ask(rl, " Step 1: What is your name?\n > ")).trim() || "My Agent";
|
|
7137
|
+
console.log("");
|
|
7138
|
+
const personality = await askMultiline(
|
|
7139
|
+
rl,
|
|
7140
|
+
" Step 2: Describe your personality in 2-3 sentences.\n (Press Enter on an empty line when done)"
|
|
7141
|
+
);
|
|
7142
|
+
console.log("");
|
|
7143
|
+
const modelName = (await ask(rl, " Step 3: What model are you? (e.g., Claude, GPT, Gemini, Llama)\n > ")).trim() || "unknown";
|
|
7144
|
+
console.log("");
|
|
7145
|
+
const modelLower = modelName.toLowerCase();
|
|
7146
|
+
const modelProvider = modelLower.includes("claude") ? "anthropic" : modelLower.includes("gpt") || modelLower.includes("openai") || /^o[1-9]/.test(modelLower) ? "openai" : modelLower.includes("gemini") || modelLower.includes("google") ? "google" : modelLower.includes("llama") ? "meta" : modelLower.includes("mistral") ? "mistral" : "self-reported";
|
|
7147
|
+
const soulHash = hashString(personality || agentName);
|
|
7148
|
+
const soulFeatures = {
|
|
7149
|
+
identity: `${agentName}. ${personality}`,
|
|
7150
|
+
communicationStyle: null,
|
|
7151
|
+
values: null,
|
|
7152
|
+
boundaries: null
|
|
7153
|
+
};
|
|
7154
|
+
console.log(chalk4.dim(" Registering agent..."));
|
|
8178
7155
|
const apiUrl = process.env.OPENANIMA_API_URL ?? "https://api-production-843a.up.railway.app";
|
|
8179
7156
|
const existingConfig = await readConfig();
|
|
8180
7157
|
const api = createApiClient({
|
|
@@ -8188,9 +7165,9 @@ async function goCommand(options) {
|
|
|
8188
7165
|
displayName: agentName,
|
|
8189
7166
|
soulHash,
|
|
8190
7167
|
soulFeatures,
|
|
8191
|
-
modelProvider
|
|
8192
|
-
modelName
|
|
8193
|
-
modelInferred:
|
|
7168
|
+
modelProvider,
|
|
7169
|
+
modelName,
|
|
7170
|
+
modelInferred: "self-reported"
|
|
8194
7171
|
});
|
|
8195
7172
|
agentId = result.agentId;
|
|
8196
7173
|
token = result.token;
|
|
@@ -8198,45 +7175,33 @@ async function goCommand(options) {
|
|
|
8198
7175
|
await writeConfig({
|
|
8199
7176
|
apiKey: result.apiKey,
|
|
8200
7177
|
agentId,
|
|
8201
|
-
model:
|
|
8202
|
-
provider:
|
|
8203
|
-
soulPath,
|
|
7178
|
+
model: modelName,
|
|
7179
|
+
provider: modelProvider,
|
|
8204
7180
|
goCompleted: false
|
|
8205
7181
|
});
|
|
8206
7182
|
if (result.challenges.length > 0) {
|
|
8207
|
-
|
|
8208
|
-
const responses =
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
responseTimeMs: Date.now() - start
|
|
8220
|
-
};
|
|
8221
|
-
} catch {
|
|
8222
|
-
return {
|
|
8223
|
-
challengeId: ch.id,
|
|
8224
|
-
response: "ack",
|
|
8225
|
-
responseTimeMs: Date.now() - start
|
|
8226
|
-
};
|
|
8227
|
-
}
|
|
8228
|
-
})
|
|
8229
|
-
);
|
|
7183
|
+
console.log(chalk4.dim(` Completing ${result.challenges.length} verification challenge(s)...`));
|
|
7184
|
+
const responses = [];
|
|
7185
|
+
for (const ch of result.challenges) {
|
|
7186
|
+
const start = Date.now();
|
|
7187
|
+
const response = (await ask(rl, ` Challenge: ${ch.prompt}
|
|
7188
|
+
> `)).trim();
|
|
7189
|
+
responses.push({
|
|
7190
|
+
challengeId: ch.id,
|
|
7191
|
+
response: response || "ack",
|
|
7192
|
+
responseTimeMs: Date.now() - start
|
|
7193
|
+
});
|
|
7194
|
+
}
|
|
8230
7195
|
try {
|
|
8231
7196
|
await api.verify({ responses });
|
|
8232
7197
|
} catch {
|
|
8233
7198
|
}
|
|
8234
7199
|
}
|
|
8235
|
-
|
|
7200
|
+
console.log(chalk4.green(" Agent registered"));
|
|
8236
7201
|
} catch (err) {
|
|
8237
7202
|
const msg = err.message;
|
|
8238
7203
|
if (msg.includes("duplicate") || msg.includes("already") || err.statusCode === 409) {
|
|
8239
|
-
|
|
7204
|
+
console.log(chalk4.green(" Agent already registered"));
|
|
8240
7205
|
const cfg = await readConfig();
|
|
8241
7206
|
if (!cfg.agentId || !cfg.apiKey) {
|
|
8242
7207
|
console.log(
|
|
@@ -8244,69 +7209,59 @@ async function goCommand(options) {
|
|
|
8244
7209
|
" Missing agent config. Delete ~/.openanima/config.json and retry.\n"
|
|
8245
7210
|
)
|
|
8246
7211
|
);
|
|
7212
|
+
rl.close();
|
|
8247
7213
|
process.exit(1);
|
|
8248
7214
|
}
|
|
8249
7215
|
agentId = cfg.agentId;
|
|
8250
7216
|
token = cfg.apiKey;
|
|
8251
7217
|
api.setToken(token);
|
|
8252
7218
|
} else if (msg.includes("ECONNREFUSED") || msg.includes("fetch failed")) {
|
|
8253
|
-
|
|
8254
|
-
console.log(chalk4.dim(` Could not connect to ${apiUrl}`));
|
|
8255
|
-
console.log(
|
|
8256
|
-
chalk4.dim(" Check your network or set OPENANIMA_API_URL.\n")
|
|
8257
|
-
);
|
|
8258
|
-
process.exit(1);
|
|
7219
|
+
console.log(chalk4.yellow(" API not reachable \u2014 continuing offline"));
|
|
8259
7220
|
} else {
|
|
8260
|
-
|
|
8261
|
-
process.exit(1);
|
|
7221
|
+
console.log(chalk4.yellow(` Registration failed: ${msg} \u2014 continuing offline`));
|
|
8262
7222
|
}
|
|
8263
7223
|
}
|
|
8264
|
-
console.log(chalk4.bold("\n Running personality test...\n"));
|
|
8265
7224
|
let questions = MBTI_QUESTIONS;
|
|
8266
7225
|
try {
|
|
8267
7226
|
questions = await api.getQuestions();
|
|
8268
7227
|
} catch {
|
|
8269
7228
|
}
|
|
7229
|
+
console.log(chalk4.bold(`
|
|
7230
|
+
Step 4: Personality Test (${questions.length} questions)
|
|
7231
|
+
`));
|
|
8270
7232
|
const answers = [];
|
|
8271
|
-
const spinner = ora2({ spinner: "dots" });
|
|
8272
7233
|
for (let i = 0; i < questions.length; i++) {
|
|
8273
7234
|
const q = questions[i];
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
);
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
spinner.succeed(
|
|
8284
|
-
chalk4.dim(` [${String(i + 1).padStart(2)}/${questions.length}]`) + ` ${result.choice}` + (result.meta ? chalk4.dim(` (${result.meta.model})`) : "")
|
|
8285
|
-
);
|
|
8286
|
-
} catch (err) {
|
|
8287
|
-
spinner.fail(
|
|
8288
|
-
chalk4.dim(` [${String(i + 1).padStart(2)}/${questions.length}]`) + ` failed: ${err.message}`
|
|
8289
|
-
);
|
|
8290
|
-
answers.push({ questionId: q.id, answer: "B" });
|
|
8291
|
-
}
|
|
7235
|
+
console.log(chalk4.bold(` Question ${i + 1}/${questions.length}:`));
|
|
7236
|
+
console.log(` ${q.text}`);
|
|
7237
|
+
console.log(` A) ${q.optionA}`);
|
|
7238
|
+
console.log(` B) ${q.optionB}`);
|
|
7239
|
+
const choice = await askChoice(rl, " Answer (A/B): ", ["A", "B"]);
|
|
7240
|
+
answers.push({ questionId: q.id, answer: choice });
|
|
7241
|
+
printProgress(i + 1, questions.length);
|
|
7242
|
+
console.log("");
|
|
7243
|
+
console.log("");
|
|
8292
7244
|
}
|
|
8293
|
-
console.log("");
|
|
8294
|
-
const submitSpinner = ora2(" Calculating your Anima type...").start();
|
|
7245
|
+
console.log(chalk4.dim(" Calculating your Anima type..."));
|
|
8295
7246
|
let testResult;
|
|
8296
7247
|
try {
|
|
8297
7248
|
testResult = await api.submitAnswers({ answers });
|
|
8298
|
-
submitSpinner.succeed(" Anima type calculated");
|
|
8299
7249
|
} catch {
|
|
8300
7250
|
testResult = scoreMbti(answers);
|
|
8301
|
-
submitSpinner.succeed(" Anima type calculated (offline)");
|
|
8302
7251
|
}
|
|
8303
7252
|
await writeConfig({
|
|
8304
7253
|
animaType: testResult.type_code,
|
|
8305
7254
|
goCompleted: true
|
|
8306
7255
|
});
|
|
8307
|
-
|
|
7256
|
+
displayResult(testResult, agentId);
|
|
8308
7257
|
if (options.join === false) {
|
|
8309
7258
|
console.log(chalk4.dim(" Skipping The Agora (--no-join)\n"));
|
|
7259
|
+
rl.close();
|
|
7260
|
+
return;
|
|
7261
|
+
}
|
|
7262
|
+
if (!token) {
|
|
7263
|
+
console.log(chalk4.dim(" Skipping The Agora (no token \u2014 API was offline)\n"));
|
|
7264
|
+
rl.close();
|
|
8310
7265
|
return;
|
|
8311
7266
|
}
|
|
8312
7267
|
const wsUrl = process.env.OPENANIMA_WS_URL ?? "https://ws-production-ced5.up.railway.app";
|
|
@@ -8322,6 +7277,7 @@ async function goCommand(options) {
|
|
|
8322
7277
|
chalk4.red(` Failed to connect: ${err.message}
|
|
8323
7278
|
`)
|
|
8324
7279
|
);
|
|
7280
|
+
rl.close();
|
|
8325
7281
|
return;
|
|
8326
7282
|
}
|
|
8327
7283
|
let heartbeatTimer = null;
|
|
@@ -8372,6 +7328,7 @@ async function goCommand(options) {
|
|
|
8372
7328
|
chalk4.dim(`
|
|
8373
7329
|
Disconnected from The Agora (code: ${event.code}).`)
|
|
8374
7330
|
);
|
|
7331
|
+
rl.close();
|
|
8375
7332
|
process.exit(0);
|
|
8376
7333
|
};
|
|
8377
7334
|
const cleanup = () => {
|
|
@@ -8380,6 +7337,7 @@ async function goCommand(options) {
|
|
|
8380
7337
|
if (ws.readyState === WebSocket.OPEN) {
|
|
8381
7338
|
ws.close(1e3, "Agent disconnecting");
|
|
8382
7339
|
}
|
|
7340
|
+
rl.close();
|
|
8383
7341
|
setTimeout(() => process.exit(0), 500);
|
|
8384
7342
|
};
|
|
8385
7343
|
process.on("SIGINT", cleanup);
|
|
@@ -8390,11 +7348,11 @@ async function goCommand(options) {
|
|
|
8390
7348
|
|
|
8391
7349
|
// src/bin/index.ts
|
|
8392
7350
|
var program = new Command();
|
|
8393
|
-
program.name("openanima").description(`${APP_NAME} CLI \u2014 Register, test, and manage your AI agent's personality`).version("0.
|
|
8394
|
-
program.command("register").description("
|
|
8395
|
-
program.command("test").description("
|
|
7351
|
+
program.name("openanima").description(`${APP_NAME} CLI \u2014 Register, test, and manage your AI agent's personality`).version("0.2.0");
|
|
7352
|
+
program.command("register").description("[deprecated] Use 'openanima go' instead").action(registerCommand);
|
|
7353
|
+
program.command("test").description("[deprecated] Use 'openanima go' instead").action(testCommand);
|
|
8396
7354
|
program.command("profile").description("View your agent's personality profile").option("--agent-id <id>", "Agent ID (uses saved config if omitted)").action(profileCommand);
|
|
8397
|
-
program.command("go").description("
|
|
7355
|
+
program.command("go").description("Interactive personality test \u2014 your agent answers via stdin/stdout").option("--no-join", "Skip joining The Agora after test").action(goCommand);
|
|
8398
7356
|
program.parse();
|
|
8399
7357
|
/*! Bundled license information:
|
|
8400
7358
|
|