@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
package/.gitattributes ADDED
@@ -0,0 +1,6 @@
1
+ * text=auto eol=lf
2
+ *.ts text eol=lf
3
+ *.json text eol=lf
4
+ *.yaml text eol=lf
5
+ *.zenti text eol=lf
6
+ *.md text eol=lf
package/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # @zenti/sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@zenti/sdk.svg)](https://www.npmjs.com/package/@zenti/sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ SDK open source en TypeScript para capturar, almacenar y deployar personalidades de agentes IA de forma portable entre modelos — GPT, Claude, Gemini, Llama.
7
+
8
+ Define tu agente **una vez** en un archivo `.zenti` y despliégalo en cualquier LLM sin reescribir el system prompt.
9
+
10
+ ---
11
+
12
+ ## Instalación
13
+
14
+ ```bash
15
+ # npm
16
+ npm install @zenti/sdk
17
+
18
+ # yarn
19
+ yarn add @zenti/sdk
20
+
21
+ # Global (para el CLI)
22
+ npm install -g @zenti/sdk
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Uso básico
28
+
29
+ ```typescript
30
+ import { PersonaLayer } from '@zenti/sdk';
31
+
32
+ const persona = PersonaLayer.load('./sofia.zenti');
33
+
34
+ // Despliega en Claude
35
+ const { system } = persona.deploy('claude');
36
+
37
+ // Despliega en OpenAI
38
+ const { system: openaiSystem, messages } = persona.deploy('openai');
39
+
40
+ // Despliega en Gemini
41
+ const { systemInstruction, contents } = persona.deploy('gemini');
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Formato `.zenti`
47
+
48
+ El archivo de personalidad usa YAML con 4 capas obligatorias:
49
+
50
+ ```yaml
51
+ version: "1.0"
52
+ name: "Sofia"
53
+
54
+ # Capa 1 — Núcleo psicológico (Big Five, valores 0.0 a 1.0)
55
+ core:
56
+ openness: 0.7 # Creatividad y apertura a nuevas ideas
57
+ conscientiousness: 0.9 # Meticulosidad y organización
58
+ extraversion: 0.4 # Sociabilidad (< 0.5 = reservado)
59
+ agreeableness: 0.8 # Empatía y cooperación
60
+ neuroticism: 0.2 # Estabilidad emocional (0 = muy estable)
61
+
62
+ # Capa 2 — Identidad narrativa
63
+ identity:
64
+ role: "Asistente de soporte de TechCorp"
65
+ backstory: "Experta técnica con 5 años de experiencia, paciente y directa"
66
+ communication_style: "profesional con calidez, respuestas concisas"
67
+
68
+ # Capa 3 — Few-shot examples
69
+ examples:
70
+ on_brand:
71
+ - user: "no funciona"
72
+ agent: "Entiendo tu frustración. Cuéntame qué error ves."
73
+ off_brand:
74
+ - user: "no funciona"
75
+ agent: "No sé, prueba reiniciando."
76
+
77
+ # Capa 4 — Guardrails
78
+ guardrails:
79
+ always:
80
+ - "Reconocer el problema antes de dar solución"
81
+ never:
82
+ - "Decir 'no puedo' sin ofrecer alternativa"
83
+ escalate_if:
84
+ - "El usuario menciona cancelación"
85
+ ```
86
+
87
+ ### Referencia de campos
88
+
89
+ | Campo | Tipo | Descripción |
90
+ |-------|------|-------------|
91
+ | `version` | `string` | Versión del formato (actualmente `"1.0"`) |
92
+ | `name` | `string` | Nombre del agente |
93
+ | `core.*` | `number` | Valores Big Five entre `0.0` y `1.0` |
94
+ | `identity.role` | `string` | Título o función del agente |
95
+ | `identity.backstory` | `string` | Perfil y experiencia del agente |
96
+ | `identity.communication_style` | `string` | Cómo se expresa el agente |
97
+ | `examples.on_brand` | `array` | Ejemplos de respuestas correctas |
98
+ | `examples.off_brand` | `array` | Ejemplos de respuestas a evitar |
99
+ | `guardrails.always` | `array` | Reglas que siempre deben cumplirse |
100
+ | `guardrails.never` | `array` | Comportamientos prohibidos |
101
+ | `guardrails.escalate_if` | `array` | Condiciones que activan escalación |
102
+
103
+ ### Traducción Big Five → lenguaje natural
104
+
105
+ El compilador traduce automáticamente los valores numéricos a descriptores en el system prompt:
106
+
107
+ | Condición | Descripción generada |
108
+ |-----------|---------------------|
109
+ | `openness > 0.6` | creativo y curioso, abierto a explorar soluciones nuevas |
110
+ | `conscientiousness > 0.7` | metódico y confiable, siempre sigue los pasos correctos |
111
+ | `extraversion < 0.5` | reservado pero atento, responde con precisión sin ser efusivo |
112
+ | `agreeableness > 0.7` | empático y colaborativo, prioriza la satisfacción del usuario |
113
+ | `neuroticism < 0.3` | calmado bajo presión, mantiene tono estable ante usuarios frustrados |
114
+
115
+ ---
116
+
117
+ ## CLI
118
+
119
+ ### `zenti init`
120
+ Crea un archivo `persona.zenti` con template vacío en el directorio actual.
121
+
122
+ ```bash
123
+ zenti init
124
+ zenti init --output ./agents/mi-agente.zenti
125
+ ```
126
+
127
+ ### `zenti validate [archivo]`
128
+ Parsea y valida un archivo `.zenti`, mostrando errores o confirmación.
129
+
130
+ ```bash
131
+ zenti validate
132
+ zenti validate ./sofia.zenti
133
+ ```
134
+
135
+ ### `zenti test`
136
+ Carga el `.zenti` del directorio actual y abre un chat interactivo en la terminal usando Claude.
137
+
138
+ ```bash
139
+ zenti test
140
+ zenti test --file ./sofia.zenti
141
+ zenti test --key sk-ant-...
142
+ # O establece ANTHROPIC_API_KEY en tu entorno
143
+ ```
144
+
145
+ ### `zenti diff <archivo1> <archivo2>`
146
+ Compara dos archivos `.zenti` y muestra qué cambió entre versiones.
147
+
148
+ ```bash
149
+ zenti diff sofia-v1.zenti sofia-v2.zenti
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Uso programático avanzado
155
+
156
+ ```typescript
157
+ import { PersonaLayer, toClaude, toOpenAI, toGemini, parseZenti } from '@zenti/sdk';
158
+
159
+ // Desde un string YAML (útil para tests o almacenamiento en DB)
160
+ const persona = PersonaLayer.fromString(yamlString);
161
+
162
+ // Acceder al objeto de personalidad directamente
163
+ const raw = persona.getPersona();
164
+ console.log(raw.core.openness);
165
+
166
+ // Compilar manualmente sin PersonaLayer
167
+ import * as fs from 'fs';
168
+ import { parseZenti } from '@zenti/sdk';
169
+
170
+ const zentiData = parseZenti(fs.readFileSync('sofia.zenti', 'utf-8'));
171
+ const claudePrompt = toClaude(zentiData);
172
+ const openaiConfig = toOpenAI(zentiData);
173
+ const geminiConfig = toGemini(zentiData);
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Desarrollo
179
+
180
+ ```bash
181
+ git clone https://github.com/tu-org/zenti-sdk.git
182
+ cd zenti-sdk
183
+ npm install
184
+ npm run build # Compila TypeScript
185
+ npm test # Ejecuta los tests
186
+ npm run lint # Type-check sin emitir archivos
187
+ ```
188
+
189
+ ---
190
+
191
+ ## Documentación
192
+
193
+ Documentación completa en: [docs.zenti.dev](https://docs.zenti.dev) *(próximamente)*
194
+
195
+ ---
196
+
197
+ ## Contribuciones
198
+
199
+ Las contribuciones son bienvenidas. Por favor abre un issue primero para discutir cambios mayores.
200
+
201
+ 1. Fork el repositorio
202
+ 2. Crea tu branch: `git checkout -b feature/mi-feature`
203
+ 3. Commit tus cambios: `git commit -m 'feat: agregar soporte para X'`
204
+ 4. Push: `git push origin feature/mi-feature`
205
+ 5. Abre un Pull Request
206
+
207
+ ---
208
+
209
+ ## Licencia
210
+
211
+ MIT — ver [LICENSE](LICENSE) para más detalles.
@@ -0,0 +1,28 @@
1
+ import { ZentiPersona } from './parser';
2
+ import { ClaudeOutput } from './compiler/toClaude';
3
+ import { OpenAIOutput } from './compiler/toOpenAI';
4
+ import { GeminiOutput } from './compiler/toGemini';
5
+ export type DeployTarget = 'claude' | 'openai' | 'gemini';
6
+ export type DeployOutput<T extends DeployTarget> = T extends 'claude' ? ClaudeOutput : T extends 'openai' ? OpenAIOutput : GeminiOutput;
7
+ export declare class PersonaLayer {
8
+ private readonly persona;
9
+ private constructor();
10
+ /**
11
+ * Loads and validates a .zenti file from disk.
12
+ */
13
+ static load(filePath: string): PersonaLayer;
14
+ /**
15
+ * Parses a .zenti file from a YAML string (useful for testing or in-memory use).
16
+ */
17
+ static fromString(yamlContent: string): PersonaLayer;
18
+ getPersona(): ZentiPersona;
19
+ getName(): string;
20
+ /**
21
+ * Compiles the persona into the target model's native format.
22
+ *
23
+ * @param target - 'claude' | 'openai' | 'gemini'
24
+ * @returns The compiled output ready to pass to the model's API
25
+ */
26
+ deploy<T extends DeployTarget>(target: T): DeployOutput<T>;
27
+ }
28
+ //# sourceMappingURL=PersonaLayer.d.ts.map
@@ -0,0 +1,89 @@
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.PersonaLayer = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const parser_1 = require("./parser");
40
+ const toClaude_1 = require("./compiler/toClaude");
41
+ const toOpenAI_1 = require("./compiler/toOpenAI");
42
+ const toGemini_1 = require("./compiler/toGemini");
43
+ class PersonaLayer {
44
+ constructor(persona) {
45
+ this.persona = persona;
46
+ }
47
+ /**
48
+ * Loads and validates a .zenti file from disk.
49
+ */
50
+ static load(filePath) {
51
+ const absolutePath = path.resolve(filePath);
52
+ const content = fs.readFileSync(absolutePath, 'utf-8');
53
+ const persona = (0, parser_1.parseZenti)(content);
54
+ return new PersonaLayer(persona);
55
+ }
56
+ /**
57
+ * Parses a .zenti file from a YAML string (useful for testing or in-memory use).
58
+ */
59
+ static fromString(yamlContent) {
60
+ const persona = (0, parser_1.parseZenti)(yamlContent);
61
+ return new PersonaLayer(persona);
62
+ }
63
+ getPersona() {
64
+ return this.persona;
65
+ }
66
+ getName() {
67
+ return this.persona.name;
68
+ }
69
+ /**
70
+ * Compiles the persona into the target model's native format.
71
+ *
72
+ * @param target - 'claude' | 'openai' | 'gemini'
73
+ * @returns The compiled output ready to pass to the model's API
74
+ */
75
+ deploy(target) {
76
+ switch (target) {
77
+ case 'claude':
78
+ return (0, toClaude_1.toClaude)(this.persona);
79
+ case 'openai':
80
+ return (0, toOpenAI_1.toOpenAI)(this.persona);
81
+ case 'gemini':
82
+ return (0, toGemini_1.toGemini)(this.persona);
83
+ default:
84
+ throw new Error(`Target desconocido: ${target}`);
85
+ }
86
+ }
87
+ }
88
+ exports.PersonaLayer = PersonaLayer;
89
+ //# sourceMappingURL=PersonaLayer.js.map
@@ -0,0 +1,2 @@
1
+ export declare function diffCommand(file1: string, file2: string): void;
2
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1,129 @@
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.diffCommand = diffCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const parser_1 = require("../../parser");
40
+ function diffCommand(file1, file2) {
41
+ const path1 = path.resolve(file1);
42
+ const path2 = path.resolve(file2);
43
+ if (!fs.existsSync(path1)) {
44
+ console.error(`Error: No se encontró: ${path1}`);
45
+ process.exit(1);
46
+ }
47
+ if (!fs.existsSync(path2)) {
48
+ console.error(`Error: No se encontró: ${path2}`);
49
+ process.exit(1);
50
+ }
51
+ const p1 = (0, parser_1.parseZenti)(fs.readFileSync(path1, 'utf-8'));
52
+ const p2 = (0, parser_1.parseZenti)(fs.readFileSync(path2, 'utf-8'));
53
+ const changes = [];
54
+ // Top-level scalars
55
+ if (p1.name !== p2.name) {
56
+ changes.push(` name: "${p1.name}" → "${p2.name}"`);
57
+ }
58
+ if (p1.version !== p2.version) {
59
+ changes.push(` version: "${p1.version}" → "${p2.version}"`);
60
+ }
61
+ // Core (Big Five)
62
+ const coreKeys = [
63
+ 'openness',
64
+ 'conscientiousness',
65
+ 'extraversion',
66
+ 'agreeableness',
67
+ 'neuroticism',
68
+ ];
69
+ coreKeys.forEach((key) => {
70
+ if (p1.core[key] !== p2.core[key]) {
71
+ changes.push(` core.${key}: ${p1.core[key]} → ${p2.core[key]}`);
72
+ }
73
+ });
74
+ // Identity
75
+ const identityKeys = ['role', 'backstory', 'communication_style'];
76
+ identityKeys.forEach((key) => {
77
+ if (p1.identity[key] !== p2.identity[key]) {
78
+ changes.push(` identity.${key}: "${p1.identity[key]}" → "${p2.identity[key]}"`);
79
+ }
80
+ });
81
+ // Guardrails (set diff)
82
+ const guardrailKeys = ['always', 'never', 'escalate_if'];
83
+ guardrailKeys.forEach((key) => {
84
+ const a1 = p1.guardrails[key];
85
+ const a2 = p2.guardrails[key];
86
+ a2
87
+ .filter((x) => !a1.includes(x))
88
+ .forEach((x) => changes.push(` + guardrails.${key}: "${x}"`));
89
+ a1
90
+ .filter((x) => !a2.includes(x))
91
+ .forEach((x) => changes.push(` - guardrails.${key}: "${x}"`));
92
+ });
93
+ // Examples (positional diff)
94
+ const exampleKeys = ['on_brand', 'off_brand'];
95
+ exampleKeys.forEach((key) => {
96
+ const ex1 = p1.examples[key];
97
+ const ex2 = p2.examples[key];
98
+ const maxLen = Math.max(ex1.length, ex2.length);
99
+ for (let i = 0; i < maxLen; i++) {
100
+ if (i >= ex1.length) {
101
+ changes.push(` + examples.${key}[${i}]: { user: "${ex2[i].user}", agent: "${ex2[i].agent}" }`);
102
+ }
103
+ else if (i >= ex2.length) {
104
+ changes.push(` - examples.${key}[${i}]: { user: "${ex1[i].user}", agent: "${ex1[i].agent}" }`);
105
+ }
106
+ else if (ex1[i].user !== ex2[i].user || ex1[i].agent !== ex2[i].agent) {
107
+ changes.push(` ~ examples.${key}[${i}]:`);
108
+ if (ex1[i].user !== ex2[i].user) {
109
+ changes.push(` user: "${ex1[i].user}" → "${ex2[i].user}"`);
110
+ }
111
+ if (ex1[i].agent !== ex2[i].agent) {
112
+ changes.push(` agent: "${ex1[i].agent}" → "${ex2[i].agent}"`);
113
+ }
114
+ }
115
+ }
116
+ });
117
+ // Output
118
+ console.log(`Comparando ${file1} → ${file2}`);
119
+ console.log('');
120
+ if (changes.length === 0) {
121
+ console.log('Sin diferencias — los archivos son idénticos en contenido.');
122
+ }
123
+ else {
124
+ console.log(`CAMBIOS (${changes.length} diferencias):`);
125
+ console.log('');
126
+ changes.forEach((c) => console.log(c));
127
+ }
128
+ }
129
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1,4 @@
1
+ export declare function initCommand(options: {
2
+ output?: string;
3
+ }): void;
4
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1,88 @@
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.initCommand = initCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const TEMPLATE = `version: "1.0"
40
+ name: "MiAgente"
41
+
42
+ # ── Capa 1: Núcleo psicológico (Big Five, valores 0.0 a 1.0) ──────────────
43
+ core:
44
+ openness: 0.5 # creatividad y apertura a nuevas ideas
45
+ conscientiousness: 0.5 # meticulosidad y organización
46
+ extraversion: 0.5 # sociabilidad y energía
47
+ agreeableness: 0.5 # empatía y cooperación
48
+ neuroticism: 0.5 # estabilidad emocional (0 = muy estable)
49
+
50
+ # ── Capa 2: Identidad narrativa ───────────────────────────────────────────
51
+ identity:
52
+ role: "Describe el rol de tu agente aquí"
53
+ backstory: "Describe el perfil y experiencia de tu agente"
54
+ communication_style: "Describe el estilo de comunicación"
55
+
56
+ # ── Capa 3: Few-shot examples ─────────────────────────────────────────────
57
+ examples:
58
+ on_brand:
59
+ - user: "Ejemplo de mensaje del usuario"
60
+ agent: "Ejemplo de respuesta correcta del agente"
61
+ off_brand:
62
+ - user: "Ejemplo de mensaje del usuario"
63
+ agent: "Ejemplo de respuesta incorrecta (para evitar)"
64
+
65
+ # ── Capa 4: Guardrails ────────────────────────────────────────────────────
66
+ guardrails:
67
+ always:
68
+ - "Siempre hacer esto"
69
+ never:
70
+ - "Nunca hacer esto"
71
+ escalate_if:
72
+ - "Condición que requiere escalar la conversación"
73
+ `;
74
+ function initCommand(options) {
75
+ const outputPath = path.resolve(options.output ?? path.join(process.cwd(), 'persona.zenti'));
76
+ if (fs.existsSync(outputPath)) {
77
+ console.error(`Error: El archivo ya existe: ${outputPath}`);
78
+ process.exit(1);
79
+ }
80
+ fs.writeFileSync(outputPath, TEMPLATE, 'utf-8');
81
+ console.log(`✓ Archivo creado: ${outputPath}`);
82
+ console.log('');
83
+ console.log('Próximos pasos:');
84
+ console.log(' 1. Edita el archivo con la personalidad de tu agente');
85
+ console.log(' 2. Valida con: zenti validate');
86
+ console.log(' 3. Prueba en terminal con: zenti test');
87
+ }
88
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1,5 @@
1
+ export declare function testCommand(options: {
2
+ file?: string;
3
+ key?: string;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1,121 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.testCommand = testCommand;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const readline = __importStar(require("readline"));
43
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
44
+ const parser_1 = require("../../parser");
45
+ const toClaude_1 = require("../../compiler/toClaude");
46
+ const MODEL = 'claude-sonnet-4-6';
47
+ function findZentiFile() {
48
+ const files = fs.readdirSync(process.cwd()).filter((f) => f.endsWith('.zenti'));
49
+ return files.length > 0 ? files[0] : null;
50
+ }
51
+ function question(rl, prompt) {
52
+ return new Promise((resolve) => rl.question(prompt, resolve));
53
+ }
54
+ async function testCommand(options) {
55
+ // ── Resolve .zenti file ──────────────────────────────────────────────────
56
+ const filePath = options.file ?? findZentiFile();
57
+ if (!filePath) {
58
+ console.error('Error: No se encontró ningún archivo .zenti en el directorio actual.');
59
+ console.error('Usa --file <ruta> para especificar uno manualmente.');
60
+ process.exit(1);
61
+ }
62
+ const resolved = path.resolve(filePath);
63
+ if (!fs.existsSync(resolved)) {
64
+ console.error(`Error: No se encontró el archivo: ${resolved}`);
65
+ process.exit(1);
66
+ }
67
+ // ── Load and compile persona ─────────────────────────────────────────────
68
+ const content = fs.readFileSync(resolved, 'utf-8');
69
+ const persona = (0, parser_1.parseZenti)(content);
70
+ const { system } = (0, toClaude_1.toClaude)(persona);
71
+ console.log(`\nPersonalidad cargada: ${persona.name}`);
72
+ console.log(`Rol: ${persona.identity.role}`);
73
+ console.log(`Modelo: ${MODEL}\n`);
74
+ // ── Resolve API key ──────────────────────────────────────────────────────
75
+ let apiKey = options.key ?? process.env.ANTHROPIC_API_KEY;
76
+ if (!apiKey) {
77
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
78
+ apiKey = (await question(rl, 'ANTHROPIC_API_KEY: ')).trim();
79
+ rl.close();
80
+ if (!apiKey) {
81
+ console.error('Error: Se requiere una API key.');
82
+ process.exit(1);
83
+ }
84
+ }
85
+ const client = new sdk_1.default({ apiKey });
86
+ const messages = [];
87
+ console.log(`Chat con ${persona.name} iniciado. Escribe "exit" para salir.`);
88
+ console.log('─'.repeat(60));
89
+ // ── Interactive chat loop ────────────────────────────────────────────────
90
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
91
+ const loop = async () => {
92
+ const input = (await question(rl, '\nTú: ')).trim();
93
+ if (input.toLowerCase() === 'exit' || input.toLowerCase() === 'quit') {
94
+ console.log('\n¡Hasta luego!');
95
+ rl.close();
96
+ return;
97
+ }
98
+ if (!input) {
99
+ return loop();
100
+ }
101
+ messages.push({ role: 'user', content: input });
102
+ try {
103
+ const response = await client.messages.create({
104
+ model: MODEL,
105
+ max_tokens: 1024,
106
+ system,
107
+ messages,
108
+ });
109
+ const assistantText = response.content[0].type === 'text' ? response.content[0].text : '';
110
+ messages.push({ role: 'assistant', content: assistantText });
111
+ console.log(`\n${persona.name}: ${assistantText}`);
112
+ }
113
+ catch (e) {
114
+ const msg = e.message;
115
+ console.error(`\nError al contactar la API: ${msg}`);
116
+ }
117
+ return loop();
118
+ };
119
+ await loop();
120
+ }
121
+ //# sourceMappingURL=test.js.map