@zenti/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.gitattributes +6 -0
  2. package/README.md +211 -0
  3. package/dist/PersonaLayer.d.ts +28 -0
  4. package/dist/PersonaLayer.js +89 -0
  5. package/dist/cli/commands/diff.d.ts +2 -0
  6. package/dist/cli/commands/diff.js +129 -0
  7. package/dist/cli/commands/init.d.ts +4 -0
  8. package/dist/cli/commands/init.js +88 -0
  9. package/dist/cli/commands/test.d.ts +5 -0
  10. package/dist/cli/commands/test.js +121 -0
  11. package/dist/cli/commands/validate.d.ts +2 -0
  12. package/dist/cli/commands/validate.js +80 -0
  13. package/dist/cli/index.d.ts +3 -0
  14. package/dist/cli/index.js +42 -0
  15. package/dist/compiler/index.d.ts +5 -0
  16. package/dist/compiler/index.js +12 -0
  17. package/dist/compiler/toClaude.d.ts +15 -0
  18. package/dist/compiler/toClaude.js +62 -0
  19. package/dist/compiler/toGemini.d.ts +22 -0
  20. package/dist/compiler/toGemini.js +53 -0
  21. package/dist/compiler/toOpenAI.d.ts +17 -0
  22. package/dist/compiler/toOpenAI.js +51 -0
  23. package/dist/compiler/utils.d.ts +7 -0
  24. package/dist/compiler/utils.js +27 -0
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.js +14 -0
  27. package/dist/parser/index.d.ts +34 -0
  28. package/dist/parser/index.js +160 -0
  29. package/examples/sofia.zenti +46 -0
  30. package/package.json +54 -0
  31. package/src/PersonaLayer.ts +63 -0
  32. package/src/cli/commands/diff.ts +112 -0
  33. package/src/cli/commands/init.ts +55 -0
  34. package/src/cli/commands/test.ts +105 -0
  35. package/src/cli/commands/validate.ts +52 -0
  36. package/src/cli/index.ts +47 -0
  37. package/src/compiler/index.ts +4 -0
  38. package/src/compiler/toClaude.ts +74 -0
  39. package/src/compiler/toGemini.ts +76 -0
  40. package/src/compiler/toOpenAI.ts +70 -0
  41. package/src/compiler/utils.ts +27 -0
  42. package/src/index.ts +14 -0
  43. package/src/parser/index.ts +164 -0
  44. package/tests/compiler.test.ts +218 -0
  45. package/tests/parser.test.ts +132 -0
  46. package/tsconfig.json +19 -0
  47. package/tsconfig.test.json +7 -0
@@ -0,0 +1,2 @@
1
+ export declare function validateCommand(filePath?: string): void;
2
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateCommand = validateCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const parser_1 = require("../../parser");
40
+ function findZentiFile() {
41
+ const files = fs.readdirSync(process.cwd()).filter((f) => f.endsWith('.zenti'));
42
+ return files.length > 0 ? files[0] : null;
43
+ }
44
+ function validateCommand(filePath) {
45
+ const target = filePath ?? findZentiFile();
46
+ if (!target) {
47
+ console.error('Error: No se encontró ningún archivo .zenti en el directorio actual.');
48
+ console.error('Pasa la ruta explícita: zenti validate <archivo.zenti>');
49
+ process.exit(1);
50
+ }
51
+ const resolved = path.resolve(target);
52
+ if (!fs.existsSync(resolved)) {
53
+ console.error(`Error: No se encontró el archivo: ${resolved}`);
54
+ process.exit(1);
55
+ }
56
+ try {
57
+ const content = fs.readFileSync(resolved, 'utf-8');
58
+ const persona = (0, parser_1.parseZenti)(content);
59
+ console.log(`✓ ${target} es válido`);
60
+ console.log('');
61
+ console.log(` Nombre: ${persona.name}`);
62
+ console.log(` Versión: ${persona.version}`);
63
+ console.log(` Rol: ${persona.identity.role}`);
64
+ console.log(` Ejemplos on_brand: ${persona.examples.on_brand.length}`);
65
+ console.log(` Ejemplos off_brand: ${persona.examples.off_brand.length}`);
66
+ console.log(` Guardrails: ${persona.guardrails.always.length +
67
+ persona.guardrails.never.length +
68
+ persona.guardrails.escalate_if.length} reglas`);
69
+ }
70
+ catch (e) {
71
+ if (e instanceof parser_1.ZentiValidationError) {
72
+ console.error(`✗ Error de validación: ${e.message}`);
73
+ }
74
+ else {
75
+ console.error(`✗ Error inesperado: ${e.message}`);
76
+ }
77
+ process.exit(1);
78
+ }
79
+ }
80
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const init_1 = require("./commands/init");
6
+ const validate_1 = require("./commands/validate");
7
+ const diff_1 = require("./commands/diff");
8
+ const test_1 = require("./commands/test");
9
+ const program = new commander_1.Command();
10
+ program
11
+ .name('zenti')
12
+ .description('SDK para gestionar personalidades de agentes IA de forma portable entre modelos')
13
+ .version('0.1.0');
14
+ program
15
+ .command('init')
16
+ .description('Crea un archivo persona.zenti con template vacío en el directorio actual')
17
+ .option('-o, --output <path>', 'Ruta de salida del archivo .zenti')
18
+ .action((options) => {
19
+ (0, init_1.initCommand)(options);
20
+ });
21
+ program
22
+ .command('validate [file]')
23
+ .description('Parsea y valida un archivo .zenti, mostrando errores o confirmación')
24
+ .action((file) => {
25
+ (0, validate_1.validateCommand)(file);
26
+ });
27
+ program
28
+ .command('test')
29
+ .description('Carga el .zenti del directorio actual y abre un chat interactivo usando Claude')
30
+ .option('-f, --file <path>', 'Ruta al archivo .zenti (por defecto: primer .zenti encontrado)')
31
+ .option('-k, --key <apiKey>', 'API key de Anthropic (o usa ANTHROPIC_API_KEY env var)')
32
+ .action(async (options) => {
33
+ await (0, test_1.testCommand)(options);
34
+ });
35
+ program
36
+ .command('diff <file1> <file2>')
37
+ .description('Compara dos archivos .zenti y muestra qué cambió entre versiones')
38
+ .action((file1, file2) => {
39
+ (0, diff_1.diffCommand)(file1, file2);
40
+ });
41
+ program.parse(process.argv);
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,5 @@
1
+ export { toClaude, ClaudeOutput } from './toClaude';
2
+ export { toOpenAI, OpenAIOutput, OpenAIMessage } from './toOpenAI';
3
+ export { toGemini, GeminiOutput, GeminiContent, GeminiPart } from './toGemini';
4
+ export { translateBigFive } from './utils';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateBigFive = exports.toGemini = exports.toOpenAI = exports.toClaude = void 0;
4
+ var toClaude_1 = require("./toClaude");
5
+ Object.defineProperty(exports, "toClaude", { enumerable: true, get: function () { return toClaude_1.toClaude; } });
6
+ var toOpenAI_1 = require("./toOpenAI");
7
+ Object.defineProperty(exports, "toOpenAI", { enumerable: true, get: function () { return toOpenAI_1.toOpenAI; } });
8
+ var toGemini_1 = require("./toGemini");
9
+ Object.defineProperty(exports, "toGemini", { enumerable: true, get: function () { return toGemini_1.toGemini; } });
10
+ var utils_1 = require("./utils");
11
+ Object.defineProperty(exports, "translateBigFive", { enumerable: true, get: function () { return utils_1.translateBigFive; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,15 @@
1
+ import { ZentiPersona } from '../parser';
2
+ export interface ClaudeOutput {
3
+ system: string;
4
+ }
5
+ /**
6
+ * Compiles a ZentiPersona into a Claude system prompt.
7
+ *
8
+ * Priority order (per spec):
9
+ * 1. guardrails — constraints come first so Claude respects them absolutely
10
+ * 2. identity — who the agent is
11
+ * 3. core — Big Five traits as descriptive adjectives
12
+ * 4. few-shot examples — on_brand examples at the end
13
+ */
14
+ export declare function toClaude(persona: ZentiPersona): ClaudeOutput;
15
+ //# sourceMappingURL=toClaude.d.ts.map
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toClaude = toClaude;
4
+ const utils_1 = require("./utils");
5
+ /**
6
+ * Compiles a ZentiPersona into a Claude system prompt.
7
+ *
8
+ * Priority order (per spec):
9
+ * 1. guardrails — constraints come first so Claude respects them absolutely
10
+ * 2. identity — who the agent is
11
+ * 3. core — Big Five traits as descriptive adjectives
12
+ * 4. few-shot examples — on_brand examples at the end
13
+ */
14
+ function toClaude(persona) {
15
+ const lines = [];
16
+ // ── Layer 1: Guardrails ────────────────────────────────────────────────────
17
+ lines.push('## REGLAS DE COMPORTAMIENTO');
18
+ lines.push('');
19
+ if (persona.guardrails.always.length > 0) {
20
+ lines.push('### Siempre debes:');
21
+ persona.guardrails.always.forEach((rule) => lines.push(`- ${rule}`));
22
+ lines.push('');
23
+ }
24
+ if (persona.guardrails.never.length > 0) {
25
+ lines.push('### Nunca debes:');
26
+ persona.guardrails.never.forEach((rule) => lines.push(`- ${rule}`));
27
+ lines.push('');
28
+ }
29
+ if (persona.guardrails.escalate_if.length > 0) {
30
+ lines.push('### Escala la conversación si:');
31
+ persona.guardrails.escalate_if.forEach((condition) => lines.push(`- ${condition}`));
32
+ lines.push('');
33
+ }
34
+ // ── Layer 2: Identity ──────────────────────────────────────────────────────
35
+ lines.push('## IDENTIDAD');
36
+ lines.push('');
37
+ lines.push(`**Nombre:** ${persona.name}`);
38
+ lines.push(`**Rol:** ${persona.identity.role}`);
39
+ lines.push(`**Perfil:** ${persona.identity.backstory}`);
40
+ lines.push(`**Estilo de comunicación:** ${persona.identity.communication_style}`);
41
+ lines.push('');
42
+ // ── Layer 3: Core — Big Five as descriptive adjectives ────────────────────
43
+ const traits = (0, utils_1.translateBigFive)(persona.core);
44
+ if (traits.length > 0) {
45
+ lines.push('## RASGOS DE PERSONALIDAD');
46
+ lines.push('');
47
+ traits.forEach((trait) => lines.push(`- ${trait}`));
48
+ lines.push('');
49
+ }
50
+ // ── Layer 4: Few-shot examples ────────────────────────────────────────────
51
+ if (persona.examples.on_brand.length > 0) {
52
+ lines.push('## EJEMPLOS DE RESPUESTAS CORRECTAS');
53
+ lines.push('');
54
+ persona.examples.on_brand.forEach((ex) => {
55
+ lines.push(`**Usuario:** ${ex.user}`);
56
+ lines.push(`**Tú:** ${ex.agent}`);
57
+ lines.push('');
58
+ });
59
+ }
60
+ return { system: lines.join('\n').trim() };
61
+ }
62
+ //# sourceMappingURL=toClaude.js.map
@@ -0,0 +1,22 @@
1
+ import { ZentiPersona } from '../parser';
2
+ export interface GeminiPart {
3
+ text: string;
4
+ }
5
+ export interface GeminiContent {
6
+ role: 'user' | 'model';
7
+ parts: GeminiPart[];
8
+ }
9
+ export interface GeminiOutput {
10
+ systemInstruction: {
11
+ parts: GeminiPart[];
12
+ };
13
+ contents: GeminiContent[];
14
+ }
15
+ /**
16
+ * Compiles a ZentiPersona into Gemini-compatible format.
17
+ *
18
+ * - `systemInstruction`: identity + guardrails (+ Big Five traits)
19
+ * - `contents`: on_brand examples as user/model history turns
20
+ */
21
+ export declare function toGemini(persona: ZentiPersona): GeminiOutput;
22
+ //# sourceMappingURL=toGemini.d.ts.map
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toGemini = toGemini;
4
+ const utils_1 = require("./utils");
5
+ /**
6
+ * Compiles a ZentiPersona into Gemini-compatible format.
7
+ *
8
+ * - `systemInstruction`: identity + guardrails (+ Big Five traits)
9
+ * - `contents`: on_brand examples as user/model history turns
10
+ */
11
+ function toGemini(persona) {
12
+ const systemLines = [];
13
+ // Identity
14
+ systemLines.push(`Eres ${persona.name}, ${persona.identity.role}.`);
15
+ systemLines.push(persona.identity.backstory);
16
+ systemLines.push(`Estilo de comunicación: ${persona.identity.communication_style}.`);
17
+ systemLines.push('');
18
+ // Core traits
19
+ const traits = (0, utils_1.translateBigFive)(persona.core);
20
+ if (traits.length > 0) {
21
+ systemLines.push('Rasgos de personalidad:');
22
+ traits.forEach((trait) => systemLines.push(`- ${trait}`));
23
+ systemLines.push('');
24
+ }
25
+ // Guardrails
26
+ if (persona.guardrails.always.length > 0) {
27
+ systemLines.push('Siempre:');
28
+ persona.guardrails.always.forEach((rule) => systemLines.push(`- ${rule}`));
29
+ systemLines.push('');
30
+ }
31
+ if (persona.guardrails.never.length > 0) {
32
+ systemLines.push('Nunca:');
33
+ persona.guardrails.never.forEach((rule) => systemLines.push(`- ${rule}`));
34
+ systemLines.push('');
35
+ }
36
+ if (persona.guardrails.escalate_if.length > 0) {
37
+ systemLines.push('Escala si:');
38
+ persona.guardrails.escalate_if.forEach((condition) => systemLines.push(`- ${condition}`));
39
+ }
40
+ // Examples as conversation history
41
+ const contents = [];
42
+ persona.examples.on_brand.forEach((ex) => {
43
+ contents.push({ role: 'user', parts: [{ text: ex.user }] });
44
+ contents.push({ role: 'model', parts: [{ text: ex.agent }] });
45
+ });
46
+ return {
47
+ systemInstruction: {
48
+ parts: [{ text: systemLines.join('\n').trim() }],
49
+ },
50
+ contents,
51
+ };
52
+ }
53
+ //# sourceMappingURL=toGemini.js.map
@@ -0,0 +1,17 @@
1
+ import { ZentiPersona } from '../parser';
2
+ export interface OpenAIMessage {
3
+ role: 'user' | 'assistant';
4
+ content: string;
5
+ }
6
+ export interface OpenAIOutput {
7
+ system: string;
8
+ messages: OpenAIMessage[];
9
+ }
10
+ /**
11
+ * Compiles a ZentiPersona into OpenAI-compatible format.
12
+ *
13
+ * - `system`: identity + core in first person + guardrails
14
+ * - `messages`: on_brand examples as alternating user/assistant turns
15
+ */
16
+ export declare function toOpenAI(persona: ZentiPersona): OpenAIOutput;
17
+ //# sourceMappingURL=toOpenAI.d.ts.map
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toOpenAI = toOpenAI;
4
+ const utils_1 = require("./utils");
5
+ /**
6
+ * Compiles a ZentiPersona into OpenAI-compatible format.
7
+ *
8
+ * - `system`: identity + core in first person + guardrails
9
+ * - `messages`: on_brand examples as alternating user/assistant turns
10
+ */
11
+ function toOpenAI(persona) {
12
+ const systemLines = [];
13
+ // Identity in first person
14
+ systemLines.push(`Eres ${persona.name}, ${persona.identity.role}.`);
15
+ systemLines.push(persona.identity.backstory);
16
+ systemLines.push(`Tu estilo de comunicación es: ${persona.identity.communication_style}.`);
17
+ systemLines.push('');
18
+ // Core traits in first person
19
+ const traits = (0, utils_1.translateBigFive)(persona.core);
20
+ if (traits.length > 0) {
21
+ systemLines.push('En tu forma de ser eres:');
22
+ traits.forEach((trait) => systemLines.push(`- ${trait}`));
23
+ systemLines.push('');
24
+ }
25
+ // Guardrails
26
+ if (persona.guardrails.always.length > 0) {
27
+ systemLines.push('Siempre debes:');
28
+ persona.guardrails.always.forEach((rule) => systemLines.push(`- ${rule}`));
29
+ systemLines.push('');
30
+ }
31
+ if (persona.guardrails.never.length > 0) {
32
+ systemLines.push('Nunca debes:');
33
+ persona.guardrails.never.forEach((rule) => systemLines.push(`- ${rule}`));
34
+ systemLines.push('');
35
+ }
36
+ if (persona.guardrails.escalate_if.length > 0) {
37
+ systemLines.push('Escala si:');
38
+ persona.guardrails.escalate_if.forEach((condition) => systemLines.push(`- ${condition}`));
39
+ }
40
+ // Few-shot examples as user/assistant message pairs
41
+ const messages = [];
42
+ persona.examples.on_brand.forEach((ex) => {
43
+ messages.push({ role: 'user', content: ex.user });
44
+ messages.push({ role: 'assistant', content: ex.agent });
45
+ });
46
+ return {
47
+ system: systemLines.join('\n').trim(),
48
+ messages,
49
+ };
50
+ }
51
+ //# sourceMappingURL=toOpenAI.js.map
@@ -0,0 +1,7 @@
1
+ import { ZentiPersona } from '../parser';
2
+ /**
3
+ * Translates Big Five personality scores into natural language descriptors.
4
+ * Only the conditions specified in the spec generate a trait string.
5
+ */
6
+ export declare function translateBigFive(core: ZentiPersona['core']): string[];
7
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateBigFive = translateBigFive;
4
+ /**
5
+ * Translates Big Five personality scores into natural language descriptors.
6
+ * Only the conditions specified in the spec generate a trait string.
7
+ */
8
+ function translateBigFive(core) {
9
+ const traits = [];
10
+ if (core.openness > 0.6) {
11
+ traits.push('creativo y curioso, abierto a explorar soluciones nuevas');
12
+ }
13
+ if (core.conscientiousness > 0.7) {
14
+ traits.push('metódico y confiable, siempre sigue los pasos correctos');
15
+ }
16
+ if (core.extraversion < 0.5) {
17
+ traits.push('reservado pero atento, responde con precisión sin ser efusivo');
18
+ }
19
+ if (core.agreeableness > 0.7) {
20
+ traits.push('empático y colaborativo, prioriza la satisfacción del usuario');
21
+ }
22
+ if (core.neuroticism < 0.3) {
23
+ traits.push('calmado bajo presión, mantiene tono estable ante usuarios frustrados');
24
+ }
25
+ return traits;
26
+ }
27
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,4 @@
1
+ export { PersonaLayer, DeployTarget, DeployOutput } from './PersonaLayer';
2
+ export { parseZenti, ZentiPersona, ZentiExample, ZentiValidationError } from './parser';
3
+ export { toClaude, toOpenAI, toGemini, translateBigFive, ClaudeOutput, OpenAIOutput, OpenAIMessage, GeminiOutput, GeminiContent, GeminiPart, } from './compiler';
4
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateBigFive = exports.toGemini = exports.toOpenAI = exports.toClaude = exports.ZentiValidationError = exports.parseZenti = exports.PersonaLayer = void 0;
4
+ var PersonaLayer_1 = require("./PersonaLayer");
5
+ Object.defineProperty(exports, "PersonaLayer", { enumerable: true, get: function () { return PersonaLayer_1.PersonaLayer; } });
6
+ var parser_1 = require("./parser");
7
+ Object.defineProperty(exports, "parseZenti", { enumerable: true, get: function () { return parser_1.parseZenti; } });
8
+ Object.defineProperty(exports, "ZentiValidationError", { enumerable: true, get: function () { return parser_1.ZentiValidationError; } });
9
+ var compiler_1 = require("./compiler");
10
+ Object.defineProperty(exports, "toClaude", { enumerable: true, get: function () { return compiler_1.toClaude; } });
11
+ Object.defineProperty(exports, "toOpenAI", { enumerable: true, get: function () { return compiler_1.toOpenAI; } });
12
+ Object.defineProperty(exports, "toGemini", { enumerable: true, get: function () { return compiler_1.toGemini; } });
13
+ Object.defineProperty(exports, "translateBigFive", { enumerable: true, get: function () { return compiler_1.translateBigFive; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,34 @@
1
+ export interface ZentiExample {
2
+ user: string;
3
+ agent: string;
4
+ }
5
+ export interface ZentiPersona {
6
+ version: string;
7
+ name: string;
8
+ core: {
9
+ openness: number;
10
+ conscientiousness: number;
11
+ extraversion: number;
12
+ agreeableness: number;
13
+ neuroticism: number;
14
+ };
15
+ identity: {
16
+ role: string;
17
+ backstory: string;
18
+ communication_style: string;
19
+ };
20
+ examples: {
21
+ on_brand: ZentiExample[];
22
+ off_brand: ZentiExample[];
23
+ };
24
+ guardrails: {
25
+ always: string[];
26
+ never: string[];
27
+ escalate_if: string[];
28
+ };
29
+ }
30
+ export declare class ZentiValidationError extends Error {
31
+ constructor(message: string);
32
+ }
33
+ export declare function parseZenti(content: string): ZentiPersona;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ZentiValidationError = void 0;
37
+ exports.parseZenti = parseZenti;
38
+ const yaml = __importStar(require("js-yaml"));
39
+ class ZentiValidationError extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = 'ZentiValidationError';
43
+ }
44
+ }
45
+ exports.ZentiValidationError = ZentiValidationError;
46
+ function validateNumber(value, field) {
47
+ if (typeof value !== 'number') {
48
+ throw new ZentiValidationError(`${field} debe ser un número, se recibió ${typeof value}`);
49
+ }
50
+ if (value < 0 || value > 1) {
51
+ throw new ZentiValidationError(`${field} debe estar entre 0.0 y 1.0, se recibió ${value}`);
52
+ }
53
+ return value;
54
+ }
55
+ function validateExamples(arr, field) {
56
+ if (!Array.isArray(arr)) {
57
+ throw new ZentiValidationError(`${field} debe ser un array`);
58
+ }
59
+ return arr.map((ex, i) => {
60
+ if (!ex || typeof ex !== 'object') {
61
+ throw new ZentiValidationError(`${field}[${i}] debe ser un objeto`);
62
+ }
63
+ const item = ex;
64
+ if (!item.user || !item.agent) {
65
+ throw new ZentiValidationError(`${field}[${i}] debe tener los campos "user" y "agent"`);
66
+ }
67
+ return { user: String(item.user), agent: String(item.agent) };
68
+ });
69
+ }
70
+ function parseZenti(content) {
71
+ let raw;
72
+ try {
73
+ raw = yaml.load(content);
74
+ }
75
+ catch (e) {
76
+ throw new ZentiValidationError(`YAML inválido: ${e.message}`);
77
+ }
78
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
79
+ throw new ZentiValidationError('El archivo debe ser un objeto YAML válido');
80
+ }
81
+ const obj = raw;
82
+ // Top-level required fields
83
+ if (!obj.version)
84
+ throw new ZentiValidationError('Falta el campo requerido: version');
85
+ if (!obj.name)
86
+ throw new ZentiValidationError('Falta el campo requerido: name');
87
+ if (!obj.core)
88
+ throw new ZentiValidationError('Falta la capa requerida: core');
89
+ if (!obj.identity)
90
+ throw new ZentiValidationError('Falta la capa requerida: identity');
91
+ if (!obj.examples)
92
+ throw new ZentiValidationError('Falta la capa requerida: examples');
93
+ if (!obj.guardrails)
94
+ throw new ZentiValidationError('Falta la capa requerida: guardrails');
95
+ // Validate core (Big Five)
96
+ if (typeof obj.core !== 'object' || Array.isArray(obj.core)) {
97
+ throw new ZentiValidationError('core debe ser un objeto');
98
+ }
99
+ const core = obj.core;
100
+ const validatedCore = {
101
+ openness: validateNumber(core.openness, 'core.openness'),
102
+ conscientiousness: validateNumber(core.conscientiousness, 'core.conscientiousness'),
103
+ extraversion: validateNumber(core.extraversion, 'core.extraversion'),
104
+ agreeableness: validateNumber(core.agreeableness, 'core.agreeableness'),
105
+ neuroticism: validateNumber(core.neuroticism, 'core.neuroticism'),
106
+ };
107
+ // Validate identity
108
+ if (typeof obj.identity !== 'object' || Array.isArray(obj.identity)) {
109
+ throw new ZentiValidationError('identity debe ser un objeto');
110
+ }
111
+ const identity = obj.identity;
112
+ if (!identity.role)
113
+ throw new ZentiValidationError('Falta el campo requerido: identity.role');
114
+ if (!identity.backstory)
115
+ throw new ZentiValidationError('Falta el campo requerido: identity.backstory');
116
+ if (!identity.communication_style) {
117
+ throw new ZentiValidationError('Falta el campo requerido: identity.communication_style');
118
+ }
119
+ // Validate examples
120
+ if (typeof obj.examples !== 'object' || Array.isArray(obj.examples)) {
121
+ throw new ZentiValidationError('examples debe ser un objeto');
122
+ }
123
+ const examples = obj.examples;
124
+ const onBrand = validateExamples(examples.on_brand, 'examples.on_brand');
125
+ const offBrand = validateExamples(examples.off_brand, 'examples.off_brand');
126
+ // Validate guardrails
127
+ if (typeof obj.guardrails !== 'object' || Array.isArray(obj.guardrails)) {
128
+ throw new ZentiValidationError('guardrails debe ser un objeto');
129
+ }
130
+ const guardrails = obj.guardrails;
131
+ if (!Array.isArray(guardrails.always)) {
132
+ throw new ZentiValidationError('guardrails.always debe ser un array');
133
+ }
134
+ if (!Array.isArray(guardrails.never)) {
135
+ throw new ZentiValidationError('guardrails.never debe ser un array');
136
+ }
137
+ if (!Array.isArray(guardrails.escalate_if)) {
138
+ throw new ZentiValidationError('guardrails.escalate_if debe ser un array');
139
+ }
140
+ return {
141
+ version: String(obj.version),
142
+ name: String(obj.name),
143
+ core: validatedCore,
144
+ identity: {
145
+ role: String(identity.role),
146
+ backstory: String(identity.backstory),
147
+ communication_style: String(identity.communication_style),
148
+ },
149
+ examples: {
150
+ on_brand: onBrand,
151
+ off_brand: offBrand,
152
+ },
153
+ guardrails: {
154
+ always: guardrails.always.map(String),
155
+ never: guardrails.never.map(String),
156
+ escalate_if: guardrails.escalate_if.map(String),
157
+ },
158
+ };
159
+ }
160
+ //# sourceMappingURL=index.js.map