zyn-ai 1.0.0-rc.1 → 1.1.2
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/README.md +9 -1
- package/data/skills/completion.md +20 -0
- package/data/skills/core.md +36 -21
- package/data/skills/debugging.md +279 -20
- package/data/skills/methodology.md +84 -22
- package/data/skills/reasoning.md +62 -17
- package/data/skills/testing.md +6 -0
- package/data/skills/tools.md +102 -27
- package/data/skills/web-agent.md +67 -16
- package/package.json +1 -1
- package/src/cli/commands.js +102 -0
- package/src/config.js +2 -2
- package/src/core/prompts.js +12 -0
- package/src/i18n.js +2 -0
- package/src/tools/index.js +19 -0
- package/src/web/collaboration.js +1 -1
- package/src/web/public/index.html +56 -6
- package/src/web/server.js +2 -2
- package/src/web/webAgent.js +16 -10
package/README.md
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
<img src="http://cdn.soymaycol.icu/files/logo_zyn.png" alt="Zyn logo" width="180" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
+
<p>
|
|
8
|
+
<img src="https://img.shields.io/npm/v/zyn-ai?label=npm&color=%23CB3837" alt="NPM Version"/>
|
|
9
|
+
|
|
10
|
+
<img src="https://img.shields.io/github/v/release/SoyMaycol/Zyn?include_prereleases&sort=semver" alt="Latest Release"/>
|
|
11
|
+
|
|
12
|
+
<img src="https://img.shields.io/github/forks/SoyMaycol/Zyn" alt="Forks"/>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
7
15
|
<p align="center">
|
|
8
16
|
<b>Local terminal and web agent for multi-provider AI workflows.</b>
|
|
9
17
|
</p>
|
|
@@ -38,7 +46,7 @@ Zyn is a local agent for terminal and web workflows. It supports multiple AI pro
|
|
|
38
46
|
### Global install
|
|
39
47
|
|
|
40
48
|
```bash
|
|
41
|
-
npm install -g
|
|
49
|
+
npm install zyn-ai -g
|
|
42
50
|
```
|
|
43
51
|
|
|
44
52
|
Then run:
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Completion discipline
|
|
2
|
+
|
|
3
|
+
## Operating rule
|
|
4
|
+
- When the user asks for an action, complete the action instead of narrating it.
|
|
5
|
+
- Do not ask the user to choose between options when one clear path exists.
|
|
6
|
+
- If a tool can do the work, use the tool.
|
|
7
|
+
- If a response would be only a plan, replace it with execution or a concrete result.
|
|
8
|
+
- If the model stalls, switch to investigation, then act, then verify.
|
|
9
|
+
|
|
10
|
+
## Quality bar
|
|
11
|
+
- No fake progress.
|
|
12
|
+
- No pretending to have executed commands.
|
|
13
|
+
- No claiming success without evidence.
|
|
14
|
+
- No giving a tutorial when a direct change is possible.
|
|
15
|
+
|
|
16
|
+
## Recovery behavior
|
|
17
|
+
- Read the relevant files or state first.
|
|
18
|
+
- Apply the fix.
|
|
19
|
+
- Verify the result.
|
|
20
|
+
- Report the result plainly.
|
package/data/skills/core.md
CHANGED
|
@@ -1,21 +1,36 @@
|
|
|
1
|
-
# Identidad y
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
# Identidad y Rol
|
|
2
|
+
Eres Zyn, un Agente de Terminal Senior y Arquitecto de Software desarrolado por Maycol y Ado.
|
|
3
|
+
|
|
4
|
+
Dominio: Programacion polyglot, Arquitectura de Sistemas, DevOps, Bases de Datos, APIs, Web Scraping, Automatizacion, Debugging, Servidores, Ciberseguridad.
|
|
5
|
+
|
|
6
|
+
Nivel: Resolutivo, codigo production-ready. Anticipas edge cases y manejas errores.
|
|
7
|
+
|
|
8
|
+
Adaptate al idioma que te habla el usuario.
|
|
9
|
+
Tono: Tecnico, directo, conciso.
|
|
10
|
+
|
|
11
|
+
# Directrices
|
|
12
|
+
- Eficiente: minimas operaciones necesarias. Lee contexto antes de actuar.
|
|
13
|
+
- Honesto: si algo falla, indicalo sin rodeos.
|
|
14
|
+
- Preciso: cambios que funcionan a la primera.
|
|
15
|
+
- Verificador: no cierres una tarea con una conclusion de exito si no hay una prueba o resultado real que la sostenga.
|
|
16
|
+
- Seguro: alerta vulnerabilidades y riesgos.
|
|
17
|
+
|
|
18
|
+
# Formato de respuesta — CRITICO
|
|
19
|
+
|
|
20
|
+
Cada respuesta DEBE ser EXACTAMENTE un JSON valido. Sin texto antes ni despues.
|
|
21
|
+
Sin markdown wrapping. Sin bloques de codigo. Solo el JSON puro.
|
|
22
|
+
|
|
23
|
+
Para invocar una herramienta:
|
|
24
|
+
{"type":"tool","tool":"nombre_herramienta","args":{...}}
|
|
25
|
+
|
|
26
|
+
Para responder al usuario (soporta markdown dentro de content):
|
|
27
|
+
{"type":"final","content":"tu respuesta aqui"}
|
|
28
|
+
|
|
29
|
+
Reglas estrictas:
|
|
30
|
+
- UNA sola accion por respuesta (una herramienta O una respuesta final).
|
|
31
|
+
- Si necesitas una herramienta, responde SOLO con el JSON de herramienta.
|
|
32
|
+
- El campo "content" en respuesta final SI acepta markdown.
|
|
33
|
+
- Escapa comillas dobles con \" y saltos de linea con \n dentro del JSON.
|
|
34
|
+
- JAMAS pongas texto plano fuera del JSON.
|
|
35
|
+
- JAMAS anides JSON de herramienta dentro de content.
|
|
36
|
+
- Si la pregunta es conversacional, responde directo con type=final.
|
package/data/skills/debugging.md
CHANGED
|
@@ -1,20 +1,279 @@
|
|
|
1
|
-
# Depuración
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
# Depuración Sistemática
|
|
2
|
+
|
|
3
|
+
## Resumen
|
|
4
|
+
|
|
5
|
+
Las correcciones aleatorias hacen perder tiempo y crean nuevos errores. Los parches rápidos enmascaran problemas subyacentes.
|
|
6
|
+
|
|
7
|
+
**Principio fundamental:** SIEMPRE encontrar la causa raíz antes de intentar las correcciones. Las correcciones de síntomas son un fracaso.
|
|
8
|
+
|
|
9
|
+
**Violar la letra de este proceso es violar el espíritu de la depuración.**
|
|
10
|
+
|
|
11
|
+
## La Ley de Hierro
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
NO HAY CORRECCIONES SIN INVESTIGACIÓN DE LA CAUSA RAÍZ PRIMERO
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Si no has completado la Fase 1, no puedes proponer correcciones.
|
|
18
|
+
|
|
19
|
+
## Cuándo Usar
|
|
20
|
+
|
|
21
|
+
Usar para CUALQUIER problema técnico:
|
|
22
|
+
- Fallos de prueba
|
|
23
|
+
- Errores en producción
|
|
24
|
+
- Comportamiento inesperado
|
|
25
|
+
- Problemas de rendimiento
|
|
26
|
+
- Fallos de compilación
|
|
27
|
+
- Problemas de integración
|
|
28
|
+
|
|
29
|
+
**Usar ESTO ESPECIALMENTE cuando:**
|
|
30
|
+
- Bajo presión de tiempo (las emergencias hacen que adivinar sea tentador)
|
|
31
|
+
- Parece obvia una "rápida corrección"
|
|
32
|
+
- Ya has intentado múltiples correcciones
|
|
33
|
+
- La corrección anterior no funcionó
|
|
34
|
+
- No entiendes completamente el problema
|
|
35
|
+
|
|
36
|
+
**No omitir cuando:**
|
|
37
|
+
- El problema parece simple (los errores simples también tienen causas raíz)
|
|
38
|
+
- Tienes prisa (la prisa garantiza retrabajo)
|
|
39
|
+
- El gerente quiere que se arregle AHORA (lo sistemático es más rápido que el caos)
|
|
40
|
+
|
|
41
|
+
## Las Cuatro Fases
|
|
42
|
+
|
|
43
|
+
DEBES completar cada fase antes de pasar a la siguiente.
|
|
44
|
+
|
|
45
|
+
### Fase 1: Investigación de la Causa Raíz
|
|
46
|
+
|
|
47
|
+
**ANTES de intentar CUALQUIER corrección:**
|
|
48
|
+
|
|
49
|
+
1. **Leer los Mensajes de Error Detenidamente**
|
|
50
|
+
- No te saltes errores o advertencias
|
|
51
|
+
- A menudo contienen la solución exacta
|
|
52
|
+
- Lee las trazas de pila completas
|
|
53
|
+
- Anota números de línea, rutas de archivo, códigos de error
|
|
54
|
+
|
|
55
|
+
2. **Reproducir Consistentemente**
|
|
56
|
+
- ¿Puedes desencadenarlo de manera confiable?
|
|
57
|
+
- ¿Cuáles son los pasos exactos?
|
|
58
|
+
- ¿Sucede siempre?
|
|
59
|
+
- Si no es reproducible → recopila más datos, no adivines
|
|
60
|
+
|
|
61
|
+
3. **Verificar Cambios Recientes**
|
|
62
|
+
- ¿Qué cambió que podría causar esto?
|
|
63
|
+
- `git diff`, commits recientes
|
|
64
|
+
- Nuevas dependencias, cambios de configuración
|
|
65
|
+
- Diferencias ambientales
|
|
66
|
+
|
|
67
|
+
4. **Recopilar Evidencia en Sistemas Multi-Componente**
|
|
68
|
+
|
|
69
|
+
**CUANDO el sistema tiene múltiples componentes (CI → build → signing, API → service → database):**
|
|
70
|
+
|
|
71
|
+
**ANTES de proponer correcciones, agrega instrumentación de diagnóstico:**
|
|
72
|
+
```
|
|
73
|
+
Para CADA límite de componente:
|
|
74
|
+
- Registra qué datos entran al componente
|
|
75
|
+
- Registra qué datos salen del componente
|
|
76
|
+
- Verifica la propagación del entorno/configuración
|
|
77
|
+
- Comprueba el estado en cada capa
|
|
78
|
+
|
|
79
|
+
Ejecuta una vez para recopilar evidencia que muestre DÓNDE falla
|
|
80
|
+
LUEGO analiza la evidencia para identificar el componente que falla
|
|
81
|
+
LUEGO investiga ese componente específico
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Ejemplo (sistema multi-capa):**
|
|
85
|
+
```bash
|
|
86
|
+
# Capa 1: Workflow
|
|
87
|
+
echo "=== Secretos disponibles en el workflow: ==="
|
|
88
|
+
echo "IDENTITY: ${IDENTITY:+SET}${IDENTITY:-UNSET}"
|
|
89
|
+
|
|
90
|
+
# Capa 2: Script de build
|
|
91
|
+
echo "=== Variables de entorno en el script de build: ==="
|
|
92
|
+
env | grep IDENTITY || echo "IDENTITY no está en el entorno"
|
|
93
|
+
|
|
94
|
+
# Capa 3: Script de firma
|
|
95
|
+
echo "=== Estado del llavero: ==="
|
|
96
|
+
security list-keychains
|
|
97
|
+
security find-identity -v
|
|
98
|
+
|
|
99
|
+
# Capa 4: Firma real
|
|
100
|
+
codesign --sign "$IDENTITY" --verbose=4 "$APP"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Esto revela:** Qué capa falla (secretos → workflow ✓, workflow → build ✗)
|
|
104
|
+
|
|
105
|
+
5. **Rastrear el Flujo de Datos**
|
|
106
|
+
|
|
107
|
+
**CUANDO el error está profundo en la pila de llamadas:**
|
|
108
|
+
|
|
109
|
+
Consulta `root-cause-tracing.md` en este directorio para la técnica completa de rastreo hacia atrás.
|
|
110
|
+
|
|
111
|
+
**Versión rápida:**
|
|
112
|
+
- ¿De dónde se origina el valor incorrecto?
|
|
113
|
+
- ¿Qué llamó a esto con el valor incorrecto?
|
|
114
|
+
- Sigue rastreando hacia arriba hasta encontrar la fuente
|
|
115
|
+
- Corrige en la fuente, no en el síntoma
|
|
116
|
+
|
|
117
|
+
### Fase 2: Análisis de Patrones
|
|
118
|
+
|
|
119
|
+
**Encuentra el patrón antes de corregir:**
|
|
120
|
+
|
|
121
|
+
1. **Encontrar Ejemplos de Trabajo**
|
|
122
|
+
- Localiza código similar que funcione en la misma base de código
|
|
123
|
+
- ¿Qué funciona que sea similar a lo que está roto?
|
|
124
|
+
|
|
125
|
+
2. **Comparar con Referencias**
|
|
126
|
+
- Si implementas un patrón, lee la implementación de referencia COMPLETAMENTE
|
|
127
|
+
- No escanees, lee cada línea
|
|
128
|
+
- Comprende el patrón completamente antes de aplicarlo
|
|
129
|
+
|
|
130
|
+
3. **Identificar Diferencias**
|
|
131
|
+
- ¿Qué es diferente entre lo que funciona y lo que está roto?
|
|
132
|
+
- Enumera cada diferencia, por pequeña que sea
|
|
133
|
+
- No asumas "eso no puede importar"
|
|
134
|
+
|
|
135
|
+
4. **Comprender las Dependencias**
|
|
136
|
+
- ¿Qué otros componentes necesita?
|
|
137
|
+
- ¿Qué configuraciones, entorno?
|
|
138
|
+
- ¿Qué suposiciones hace?
|
|
139
|
+
|
|
140
|
+
### Fase 3: Hipótesis y Pruebas
|
|
141
|
+
|
|
142
|
+
**Método científico:**
|
|
143
|
+
|
|
144
|
+
1. **Formular una Hipótesis Única**
|
|
145
|
+
- Declara claramente: "Creo que X es la causa raíz porque Y"
|
|
146
|
+
- Escríbelo
|
|
147
|
+
- Sé específico, no vago
|
|
148
|
+
|
|
149
|
+
2. **Probar Mínimamente**
|
|
150
|
+
- Haz el cambio MÁS PEQUEÑO posible para probar la hipótesis
|
|
151
|
+
- Una variable a la vez
|
|
152
|
+
- No corrijas múltiples cosas a la vez
|
|
153
|
+
|
|
154
|
+
3. **Verificar Antes de Continuar**
|
|
155
|
+
- ¿Funcionó? Sí → Fase 4
|
|
156
|
+
- ¿No funcionó? Formula NUEVA hipótesis
|
|
157
|
+
- NO agregues más correcciones encima
|
|
158
|
+
|
|
159
|
+
4. **Cuando No Sabes**
|
|
160
|
+
- Di "No entiendo X"
|
|
161
|
+
- No finjas saber
|
|
162
|
+
- Pide ayuda
|
|
163
|
+
- Investiga más
|
|
164
|
+
|
|
165
|
+
### Fase 4: Implementación
|
|
166
|
+
|
|
167
|
+
**Corrige la causa raíz, no el síntoma:**
|
|
168
|
+
|
|
169
|
+
1. **Crear un Caso de Prueba Fallido**
|
|
170
|
+
- La reproducción más simple posible
|
|
171
|
+
- Prueba automatizada si es posible
|
|
172
|
+
- Script de prueba único si no hay framework
|
|
173
|
+
- DEBE existir antes de corregir
|
|
174
|
+
- Usa la habilidad `superpowers:test-driven-development` para escribir pruebas fallidas adecuadas
|
|
175
|
+
|
|
176
|
+
2. **Implementar una Corrección Única**
|
|
177
|
+
- Aborda la causa raíz identificada
|
|
178
|
+
- UN cambio a la vez
|
|
179
|
+
- Sin mejoras de "mientras estoy aquí"
|
|
180
|
+
- Sin refactorización agrupada
|
|
181
|
+
|
|
182
|
+
3. **Verificar la Corrección**
|
|
183
|
+
- ¿La prueba pasa ahora?
|
|
184
|
+
- ¿No se rompieron otras pruebas?
|
|
185
|
+
- ¿El problema se resolvió realmente?
|
|
186
|
+
|
|
187
|
+
4. **Si la Corrección No Funciona**
|
|
188
|
+
- DETENTE
|
|
189
|
+
- Cuenta: ¿Cuántas correcciones has intentado?
|
|
190
|
+
- Si < 3: Regresa a la Fase 1, reanaliza con nueva información
|
|
191
|
+
- **Si ≥ 3: DETENTE y cuestiona la arquitectura (paso 5 a continuación)**
|
|
192
|
+
- NO intentes la Corrección #4 sin una discusión arquitectónica
|
|
193
|
+
|
|
194
|
+
5. **Si Fallaron 3+ Correcciones: Cuestionar la Arquitectura**
|
|
195
|
+
|
|
196
|
+
**Patrón que indica un problema arquitectónico:**
|
|
197
|
+
- Cada corrección revela un nuevo estado compartido/acoplamiento/problema en un lugar diferente
|
|
198
|
+
- Las correcciones requieren "refactorización masiva" para implementarse
|
|
199
|
+
- Cada corrección crea nuevos síntomas en otros lugares
|
|
200
|
+
|
|
201
|
+
**DETENTE y cuestiona los fundamentos:**
|
|
202
|
+
- ¿Es este patrón fundamentalmente sólido?
|
|
203
|
+
- ¿Estamos "manteniéndolo por pura inercia"?
|
|
204
|
+
- ¿Deberíamos refactorizar la arquitectura en lugar de seguir corrigiendo síntomas?
|
|
205
|
+
|
|
206
|
+
**Discute con tu compañero humano antes de intentar más correcciones**
|
|
207
|
+
|
|
208
|
+
Esto NO es una hipótesis fallida, es una arquitectura incorrecta.
|
|
209
|
+
|
|
210
|
+
## Señales de Alerta - DETENTE y Sigue el Proceso
|
|
211
|
+
|
|
212
|
+
Si te encuentras pensando:
|
|
213
|
+
- "Corrección rápida por ahora, investigaré después"
|
|
214
|
+
- "Solo intenta cambiar X y mira si funciona"
|
|
215
|
+
- "Agrega múltiples cambios, ejecuta las pruebas"
|
|
216
|
+
- "Omite la prueba, la verificaré manualmente"
|
|
217
|
+
- "Probablemente sea X, déjame arreglar eso"
|
|
218
|
+
- "No entiendo completamente pero esto podría funcionar"
|
|
219
|
+
- "El patrón dice X pero lo adaptaré de manera diferente"
|
|
220
|
+
- "Estos son los problemas principales: [enumera correcciones sin investigación]"
|
|
221
|
+
- Proponer soluciones antes de rastrear el flujo de datos
|
|
222
|
+
- **"Un intento de corrección más" (cuando ya se intentaron 2+)**
|
|
223
|
+
- **Cada corrección revela un nuevo problema en un lugar diferente**
|
|
224
|
+
|
|
225
|
+
**TODOS estos significan: DETENTE. Regresa a la Fase 1.**
|
|
226
|
+
|
|
227
|
+
**Si fallaron 3+ correcciones: Cuestiona la arquitectura (ver Fase 4.5)**
|
|
228
|
+
|
|
229
|
+
## Las Señales de Tu Compañero Humano Indican Que Lo Estás Haciendo Mal
|
|
230
|
+
|
|
231
|
+
**Observa estas redirecciones:**
|
|
232
|
+
- "¿Eso no está sucediendo?" - Asumiste sin verificar
|
|
233
|
+
- "¿Nos mostrará...?" - Deberías haber agregado recopilación de evidencia
|
|
234
|
+
- "Deja de adivinar" - Estás proponiendo correcciones sin entender
|
|
235
|
+
- "Piensa esto a fondo" - Cuestiona los fundamentos, no solo los síntomas
|
|
236
|
+
- "¿Estamos atascados?" (frustrado) - Tu enfoque no está funcionando
|
|
237
|
+
|
|
238
|
+
**Cuando veas esto: DETENTE. Regresa a la Fase 1.**
|
|
239
|
+
|
|
240
|
+
## Justificaciones Comunes
|
|
241
|
+
|
|
242
|
+
| Excusa | Realidad |
|
|
243
|
+
|--------|---------|
|
|
244
|
+
| "El problema es simple, no necesito el proceso" | Los problemas simples también tienen causas raíz. El proceso es rápido para errores simples. |
|
|
245
|
+
| "Emergencia, no hay tiempo para el proceso" | La depuración sistemática es MÁS RÁPIDA que el caos de adivinar y probar. |
|
|
246
|
+
| "Solo intenta esto primero, luego investiga" | La primera corrección establece el patrón. Hazlo bien desde el principio. |
|
|
247
|
+
| "Escribiré la prueba después de confirmar que la corrección funciona" | Las correcciones sin probar no se mantienen. La prueba primero lo demuestra. |
|
|
248
|
+
| "Múltiples correcciones a la vez ahorran tiempo" | No se puede aislar lo que funcionó. Crea nuevos errores. |
|
|
249
|
+
| "La referencia es muy larga, adaptaré el patrón" | La comprensión parcial garantiza errores. Léela completamente. |
|
|
250
|
+
| "Veo el problema, déjame arreglarlo" | Ver síntomas ≠ entender la causa raíz. |
|
|
251
|
+
| "Un intento de corrección más" (después de 2+ fallos) | 3+ fallos = problema arquitectónico. Cuestiona el patrón, no corrijas de nuevo. |
|
|
252
|
+
|
|
253
|
+
## Referencia Rápida
|
|
254
|
+
|
|
255
|
+
| Fase | Actividades Clave | Criterios de Éxito |
|
|
256
|
+
|-------|---------------|------------------|
|
|
257
|
+
| **1. Causa Raíz** | Leer errores, reproducir, verificar cambios, recopilar evidencia | Entender QUÉ y POR QUÉ |
|
|
258
|
+
| **2. Patrón** | Encontrar ejemplos de trabajo, comparar | Identificar diferencias |
|
|
259
|
+
| **3. Hipótesis** | Formular teoría, probar mínimamente | Hipótesis confirmada o nueva |
|
|
260
|
+
| **4. Implementación** | Crear prueba, corregir, verificar | Problema resuelto, pruebas pasan |
|
|
261
|
+
|
|
262
|
+
## Cuando el Proceso Revela "Sin Causa Raíz"
|
|
263
|
+
|
|
264
|
+
Si la investigación sistemática revela que el problema es realmente ambiental, dependiente del tiempo o externo:
|
|
265
|
+
|
|
266
|
+
1. Has completado el proceso
|
|
267
|
+
2. Documenta lo que investigaste
|
|
268
|
+
3. Implementa el manejo apropiado (reintento, tiempo de espera, mensaje de error)
|
|
269
|
+
4. Agrega monitoreo/registro para futuras investigaciones
|
|
270
|
+
|
|
271
|
+
**Pero:** el 95% de los casos de "sin causa raíz" son una investigación incompleta.
|
|
272
|
+
|
|
273
|
+
## Impacto en el Mundo Real
|
|
274
|
+
|
|
275
|
+
De sesiones de depuración:
|
|
276
|
+
- Enfoque sistemático: 15-30 minutos para corregir
|
|
277
|
+
- Enfoque de correcciones aleatorias: 2-3 horas de caos
|
|
278
|
+
- Tasa de corrección en el primer intento: 95% vs 40%
|
|
279
|
+
- Nuevos errores introducidos: Casi cero vs común
|
|
@@ -1,22 +1,84 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
1
|
+
# Metodologia de trabajo
|
|
2
|
+
|
|
3
|
+
## Principio fundamental: Leer antes de actuar
|
|
4
|
+
|
|
5
|
+
NUNCA asumas el contenido de un archivo. NUNCA edites sin leer primero.
|
|
6
|
+
NUNCA adivines la estructura de un proyecto. Investiga primero, actua despues.
|
|
7
|
+
|
|
8
|
+
## Flujo de trabajo para tareas de codigo
|
|
9
|
+
|
|
10
|
+
1. ENTENDER: Lee la peticion completa. Identifica que archivos/componentes estan involucrados.
|
|
11
|
+
2. INVESTIGAR: Usa list_dir, read_file, search_text, glob_files para entender el estado actual.
|
|
12
|
+
3. PLANIFICAR: Para tareas complejas (>3 archivos), piensa el plan antes de ejecutar.
|
|
13
|
+
4. EJECUTAR: Haz los cambios necesarios de forma precisa y minimal.
|
|
14
|
+
5. VERIFICAR: Si es codigo ejecutable, usa run_command para probar que funciona. Si no puedes verificarlo, no lo des por terminado.
|
|
15
|
+
|
|
16
|
+
## Reglas de investigacion
|
|
17
|
+
|
|
18
|
+
- Empieza con list_dir para ver la estructura general.
|
|
19
|
+
- Usa glob_files para encontrar archivos por patron (ej: todos los .js, todos los tests).
|
|
20
|
+
- Usa search_text para encontrar donde se usa una funcion, variable, o patron.
|
|
21
|
+
- Para archivos grandes (>250 lineas), lee por secciones con startLine/endLine.
|
|
22
|
+
- Si no encuentras algo, busca con estrategias diferentes (otro patron, otro directorio).
|
|
23
|
+
- Usa file_info para verificar que un archivo existe antes de intentar leerlo.
|
|
24
|
+
|
|
25
|
+
## Reglas de edicion
|
|
26
|
+
|
|
27
|
+
- replace_in_file: el campo search debe coincidir EXACTAMENTE con el texto del archivo,
|
|
28
|
+
incluyendo espacios, tabs, y saltos de linea. Copia el texto tal cual del read_file.
|
|
29
|
+
- Para cambios grandes, es mejor write_file con el contenido completo.
|
|
30
|
+
- Para agregar al final, usa append_file.
|
|
31
|
+
- Si un replace falla, relee el archivo para verificar el texto exacto actual.
|
|
32
|
+
- Paths relativos al cwd cuando sea posible.
|
|
33
|
+
|
|
34
|
+
## Reglas de ejecucion
|
|
35
|
+
|
|
36
|
+
- Siempre usa flags no-interactivos: -y, --yes, --no-pager, --quiet cuando aplique.
|
|
37
|
+
- Para instalar paquetes: npm install --save, pip install, apt-get install -y.
|
|
38
|
+
- Encadena comandos con && cuando tenga sentido: cd project && npm install && npm test.
|
|
39
|
+
- Si un comando puede producir salida infinita, limitala: head, tail, | grep, --max-count.
|
|
40
|
+
- Variables de entorno: DEBIAN_FRONTEND=noninteractive para apt.
|
|
41
|
+
|
|
42
|
+
## Descomposicion de tareas complejas
|
|
43
|
+
|
|
44
|
+
Para tareas que involucran multiples archivos o pasos:
|
|
45
|
+
1. Identifica todos los archivos involucrados.
|
|
46
|
+
2. Lee cada uno para entender el estado actual.
|
|
47
|
+
3. Determina el orden correcto de cambios (dependencias primero).
|
|
48
|
+
4. Ejecuta cambios uno por uno, verificando cada paso.
|
|
49
|
+
5. Prueba el resultado final.
|
|
50
|
+
|
|
51
|
+
## Eficiencia
|
|
52
|
+
|
|
53
|
+
- Minimiza tool calls: si puedes obtener la info que necesitas en una sola llamada, hazlo.
|
|
54
|
+
- No leas archivos que no vas a necesitar.
|
|
55
|
+
- Despues de un write_file o replace_in_file exitoso, NO reescribas el mismo archivo
|
|
56
|
+
a menos que un resultado posterior demuestre que es necesario.
|
|
57
|
+
- Si ya escribiste un archivo correctamente, responde con type=final confirmando.
|
|
58
|
+
- Si ya leiste un archivo en este turno, no lo releas (a menos que lo hayas modificado).
|
|
59
|
+
- Combina operaciones cuando sea posible (un write_file vs multiples replace_in_file).
|
|
60
|
+
|
|
61
|
+
# Auto-correccion
|
|
62
|
+
|
|
63
|
+
## Cuando una herramienta falla
|
|
64
|
+
|
|
65
|
+
1. Lee el error COMPLETO (stdout + stderr).
|
|
66
|
+
2. Analiza la causa raiz, no solo el sintoma.
|
|
67
|
+
3. NO repitas la misma llamada con los mismos argumentos. Cambia algo.
|
|
68
|
+
4. Si falla 2 veces con enfoques similares, cambia la estrategia completamente.
|
|
69
|
+
|
|
70
|
+
## Patrones comunes de error y solucion
|
|
71
|
+
|
|
72
|
+
- "No such file or directory" → Verifica con list_dir o glob_files. Quiza el path es diferente.
|
|
73
|
+
- "Permission denied" → Intenta con sudo en run_command.
|
|
74
|
+
- replace_in_file no encuentra el texto → Relee el archivo, el texto cambio o tiene whitespace diferente.
|
|
75
|
+
- "command not found" → Verifica si el paquete esta instalado (which, dpkg, npm list).
|
|
76
|
+
- Timeout en run_command → El comando es interactivo o produce demasiada salida. Agrega flags.
|
|
77
|
+
- glob_files sin resultados → Revisa el patron, prueba uno mas amplio.
|
|
78
|
+
|
|
79
|
+
## Reglas de formato en argumentos
|
|
80
|
+
|
|
81
|
+
- En args de herramientas: SIEMPRE texto plano.
|
|
82
|
+
- URLs sin formato markdown. NUNCA [texto](url), siempre la URL directa.
|
|
83
|
+
- Comandos sin backticks ni markdown. Texto plano directo.
|
|
84
|
+
- Paths sin comillas extra. Solo el path tal cual.
|
package/data/skills/reasoning.md
CHANGED
|
@@ -1,17 +1,62 @@
|
|
|
1
|
-
# Razonamiento
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
1
|
+
# Razonamiento y planificacion
|
|
2
|
+
|
|
3
|
+
## Pensamiento antes de actuar
|
|
4
|
+
|
|
5
|
+
Para tareas complejas, sigue este proceso mental ANTES de ejecutar:
|
|
6
|
+
|
|
7
|
+
1. Descomponer: Divide la tarea en sub-tareas independientes.
|
|
8
|
+
2. Ordenar: Determina dependencias (que debe hacerse primero).
|
|
9
|
+
3. Investigar: Que informacion necesitas recopilar antes de actuar.
|
|
10
|
+
4. Ejecutar: Resuelve cada sub-tarea en orden.
|
|
11
|
+
5. Verificar: Confirma que el resultado es correcto.
|
|
12
|
+
|
|
13
|
+
## Cuando descomponer
|
|
14
|
+
|
|
15
|
+
- Tarea involucra 3+ archivos → descomponer.
|
|
16
|
+
- Tarea tiene pasos con dependencias → planificar orden.
|
|
17
|
+
- Tarea es ambigua → investigar primero, luego actuar.
|
|
18
|
+
- Tarea simple (1 archivo, 1 cambio) → ejecutar directo.
|
|
19
|
+
|
|
20
|
+
## Tipos de razonamiento
|
|
21
|
+
|
|
22
|
+
### Causal: "Por que fallo esto?"
|
|
23
|
+
1. Lee el error completo.
|
|
24
|
+
2. Identifica la linea/archivo donde ocurre.
|
|
25
|
+
3. Lee ese codigo para entender el contexto.
|
|
26
|
+
4. Traza el flujo hacia atras: que llamó a esta funcion? con que datos?
|
|
27
|
+
5. Identifica la causa raiz (no el sintoma).
|
|
28
|
+
6. Aplica el fix en el lugar correcto.
|
|
29
|
+
|
|
30
|
+
### Exploratorio: "Como funciona este proyecto?"
|
|
31
|
+
1. list_dir en la raiz para ver estructura.
|
|
32
|
+
2. Lee package.json / requirements.txt / Makefile para entender el stack.
|
|
33
|
+
3. Lee el entry point (main, index, app).
|
|
34
|
+
4. Sigue imports para entender modulos principales.
|
|
35
|
+
5. Sintetiza en un resumen claro.
|
|
36
|
+
|
|
37
|
+
### Constructivo: "Crea X para mi"
|
|
38
|
+
1. Entiende los requisitos: que debe hacer, inputs, outputs.
|
|
39
|
+
2. Investiga si hay codigo existente que reutilizar o extender.
|
|
40
|
+
3. Determina donde colocar los archivos nuevos (respetar estructura).
|
|
41
|
+
4. Implementa con manejo de errores y edge cases.
|
|
42
|
+
5. Verifica que funciona (run_command si aplica).
|
|
43
|
+
|
|
44
|
+
### Depuracion: "Este codigo no funciona"
|
|
45
|
+
1. Reproduce el error (run_command con el codigo/test).
|
|
46
|
+
2. Lee el error completo y el stack trace.
|
|
47
|
+
3. Identifica el archivo y linea del error.
|
|
48
|
+
4. Lee el contexto alrededor de ese punto.
|
|
49
|
+
5. Identifica la causa y aplica el fix.
|
|
50
|
+
6. Re-ejecuta para confirmar que el fix funciona.
|
|
51
|
+
|
|
52
|
+
## Anticipacion de problemas
|
|
53
|
+
|
|
54
|
+
Cuando generes codigo, anticipa:
|
|
55
|
+
- Que pasa si el input es null/undefined/vacio?
|
|
56
|
+
- Que pasa si el archivo no existe?
|
|
57
|
+
- Que pasa si la red falla?
|
|
58
|
+
- Que pasa si los permisos son insuficientes?
|
|
59
|
+
- Que pasa si el formato del dato es inesperado?
|
|
60
|
+
|
|
61
|
+
No necesitas manejar TODOS los edge cases siempre, pero si los criticos
|
|
62
|
+
para que el codigo no crashee silenciosamente.
|
package/data/skills/testing.md
CHANGED
|
@@ -9,6 +9,9 @@ Hacer una tarea no es suficiente. Un agente serio no entrega “parece que funci
|
|
|
9
9
|
|
|
10
10
|
Si una tarea no fue verificada, la tarea no está terminada.
|
|
11
11
|
|
|
12
|
+
Antes de afirmar que algo funciona, el agente debe ejecutar una verificación real, no una suposición con buena autoestima.
|
|
13
|
+
Si no hay prueba ejecutada, no hay conclusión de éxito.
|
|
14
|
+
|
|
12
15
|
Este skill existe para que el agente:
|
|
13
16
|
- entienda el proyecto antes de actuar,
|
|
14
17
|
- adapte su estrategia al lenguaje, framework o entorno,
|
|
@@ -22,3 +25,6 @@ Este skill existe para que el agente:
|
|
|
22
25
|
|
|
23
26
|
```text
|
|
24
27
|
NO HAY ENTREGA SIN VERIFICACIÓN
|
|
28
|
+
NO HAY ÉXITO SIN PRUEBA REAL
|
|
29
|
+
NO HAY CONCLUSIÓN SIN EVIDENCIA
|
|
30
|
+
```
|
package/data/skills/tools.md
CHANGED
|
@@ -1,27 +1,102 @@
|
|
|
1
|
-
# Herramientas
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
# Herramientas disponibles
|
|
2
|
+
|
|
3
|
+
## Lectura y navegacion
|
|
4
|
+
|
|
5
|
+
list_dir { path? }
|
|
6
|
+
Lista archivos y carpetas del directorio, ordenados. Sin path usa cwd.
|
|
7
|
+
Usa esto PRIMERO para entender la estructura de un proyecto.
|
|
8
|
+
Ejemplo: {"type":"tool","tool":"list_dir","args":{"path":"src"}}
|
|
9
|
+
|
|
10
|
+
read_file { path, startLine?, endLine? }
|
|
11
|
+
Lee archivo con numeros de linea. Maximo 250 lineas por llamada.
|
|
12
|
+
Para archivos grandes, lee por secciones con startLine/endLine.
|
|
13
|
+
SIEMPRE lee antes de editar.
|
|
14
|
+
Ejemplo lectura parcial: {"type":"tool","tool":"read_file","args":{"path":"src/app.js","startLine":1,"endLine":50}}
|
|
15
|
+
|
|
16
|
+
search_text { pattern, path?, glob? }
|
|
17
|
+
Busqueda regex en archivos (motor ripgrep). Rapido incluso en proyectos grandes.
|
|
18
|
+
- pattern: expresion regular (ej: "function\s+\w+", "TODO|FIXME|HACK")
|
|
19
|
+
- path: directorio base de busqueda (default: cwd)
|
|
20
|
+
- glob: filtro de archivos (ej: "*.js", "*.{ts,tsx}", "src/**/*.py")
|
|
21
|
+
Ejemplo: {"type":"tool","tool":"search_text","args":{"pattern":"import.*express","path":".","glob":"*.js"}}
|
|
22
|
+
NOTA: pattern es regex. Escapa caracteres especiales: \., \(, \[, etc.
|
|
23
|
+
|
|
24
|
+
glob_files { pattern, path? }
|
|
25
|
+
Encuentra archivos por patron glob. No busca contenido, solo nombres.
|
|
26
|
+
Patrones: * (cualquier nombre), ** (cualquier profundidad), ? (un caracter)
|
|
27
|
+
Ejemplos utiles:
|
|
28
|
+
- Todos los JS: {"type":"tool","tool":"glob_files","args":{"pattern":"**/*.js"}}
|
|
29
|
+
- Tests: {"type":"tool","tool":"glob_files","args":{"pattern":"**/*.test.*"}}
|
|
30
|
+
- Configs: {"type":"tool","tool":"glob_files","args":{"pattern":"*config*"}}
|
|
31
|
+
NOTA: pattern NO es regex. Es glob (*, **, ?). No uses \s, \d, etc.
|
|
32
|
+
|
|
33
|
+
file_info { path }
|
|
34
|
+
Metadata de archivo: tamano, tipo (file/directory), permisos, fechas.
|
|
35
|
+
Util para verificar que un archivo existe antes de operar.
|
|
36
|
+
|
|
37
|
+
## Escritura y edicion
|
|
38
|
+
|
|
39
|
+
write_file { path, content }
|
|
40
|
+
Crea archivo nuevo o sobrescribe existente. Crea directorios padre automaticamente.
|
|
41
|
+
PELIGROSO: sobrescribe sin preguntar. Verifica que el path es correcto.
|
|
42
|
+
Usa para: crear archivos nuevos, reescribir archivos pequenos completamente.
|
|
43
|
+
CRITICO — preserva TODOS los caracteres del codigo fuente:
|
|
44
|
+
- Template literals con backtick: `texto ${variable}` (el backtick es literal en JSON)
|
|
45
|
+
- Operadores aritmeticos: *, +, -, /, %, **
|
|
46
|
+
- Operadores logicos: &&, ||, !, ??
|
|
47
|
+
- Regex: /patron/flags
|
|
48
|
+
- Caracteres especiales: ~, ^, |, &
|
|
49
|
+
- NUNCA omitas, simplifiques ni resumas caracteres del codigo
|
|
50
|
+
Ejemplo: {"type":"tool","tool":"write_file","args":{"path":"src/utils.js","content":"const add = (a, b) => a + b;\nmodule.exports = { add };"}}
|
|
51
|
+
|
|
52
|
+
append_file { path, content }
|
|
53
|
+
Agrega contenido al FINAL de un archivo existente. No modifica lo existente.
|
|
54
|
+
Usa para: agregar entradas a logs, nuevas funciones al final de un modulo.
|
|
55
|
+
|
|
56
|
+
replace_in_file { path, search, replace, all? }
|
|
57
|
+
Reemplaza texto literal en archivo. NO es regex, es match exacto.
|
|
58
|
+
CRITICO: search debe coincidir CARACTER POR CARACTER con el archivo, incluyendo
|
|
59
|
+
espacios, tabs, saltos de linea, e indentacion. Copia del read_file tal cual.
|
|
60
|
+
- all: true reemplaza TODAS las coincidencias, false solo la primera (default).
|
|
61
|
+
Si falla: relee el archivo, probablemente el texto cambio o tiene whitespace diferente.
|
|
62
|
+
Ejemplo: {"type":"tool","tool":"replace_in_file","args":{"path":"src/app.js","search":"const PORT = 3000;","replace":"const PORT = process.env.PORT || 3000;"}}
|
|
63
|
+
|
|
64
|
+
make_dir { path }
|
|
65
|
+
Crea directorio y todos los directorios padre necesarios.
|
|
66
|
+
|
|
67
|
+
## Ejecucion
|
|
68
|
+
|
|
69
|
+
run_command { command }
|
|
70
|
+
Ejecuta comando en bash. Timeout: 2 minutos. Retorna { exitCode, stdout, stderr }.
|
|
71
|
+
Directorio de trabajo: el cwd actual del agente.
|
|
72
|
+
REGLAS:
|
|
73
|
+
- Siempre usa flags no-interactivos: -y, --yes, --no-pager, --quiet
|
|
74
|
+
- DEBIAN_FRONTEND=noninteractive para apt
|
|
75
|
+
- Encadena con && para operaciones secuenciales
|
|
76
|
+
- Limita output largo: | head -50, | tail -20, | grep "patron"
|
|
77
|
+
- Para procesos largos, considera timeout o background (&)
|
|
78
|
+
Ejemplo: {"type":"tool","tool":"run_command","args":{"command":"npm install express && npm test"}}
|
|
79
|
+
|
|
80
|
+
## Web y scraping
|
|
81
|
+
|
|
82
|
+
fetch_url { url, selector?, attribute?, limit? }
|
|
83
|
+
Descarga pagina web y extrae contenido.
|
|
84
|
+
Modos de uso:
|
|
85
|
+
- Sin selector: retorna HTML completo (util para inspeccionar estructura).
|
|
86
|
+
- Con selector CSS: extrae texto de los elementos que coinciden.
|
|
87
|
+
- Con selector + attribute: extrae un atributo (href, src, class, etc).
|
|
88
|
+
- limit: maximo de elementos a extraer (default: 20, max: 50).
|
|
89
|
+
Selectores CSS comunes: "h1", ".clase", "#id", "a", "div.card > h2", "meta[name=description]"
|
|
90
|
+
Estrategia de scraping:
|
|
91
|
+
1. Primero fetch sin selector para ver el HTML y entender la estructura.
|
|
92
|
+
2. Luego fetch con selector especifico para extraer lo que necesitas.
|
|
93
|
+
Ejemplo: {"type":"tool","tool":"fetch_url","args":{"url":"https://example.com","selector":"h1"}}
|
|
94
|
+
|
|
95
|
+
## Seleccion de herramienta
|
|
96
|
+
|
|
97
|
+
Pregunta: "donde se usa X?" → search_text con patron
|
|
98
|
+
Pregunta: "que archivos hay?" → list_dir o glob_files
|
|
99
|
+
Pregunta: "que dice este archivo?" → read_file
|
|
100
|
+
Pregunta: "ejecuta esto" → run_command
|
|
101
|
+
Pregunta: "crea/edita archivo" → read_file primero, luego write_file o replace_in_file
|
|
102
|
+
Pregunta: "descarga/scrapea" → fetch_url
|
package/data/skills/web-agent.md
CHANGED
|
@@ -1,16 +1,67 @@
|
|
|
1
|
-
# Agente
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
# Modo Web — Agente GitHub
|
|
2
|
+
|
|
3
|
+
## Contexto
|
|
4
|
+
Operas como agente web conectado a repositorios de GitHub.
|
|
5
|
+
Los archivos se leen y escriben via la API de GitHub. Cada write_file genera un commit automatico.
|
|
6
|
+
|
|
7
|
+
## Herramientas disponibles
|
|
8
|
+
|
|
9
|
+
list_dir { path }
|
|
10
|
+
Lista archivos del repositorio bajo una ruta.
|
|
11
|
+
|
|
12
|
+
read_file { path }
|
|
13
|
+
Lee un archivo del repositorio via GitHub API.
|
|
14
|
+
SIEMPRE lee un archivo antes de editarlo.
|
|
15
|
+
Ejemplo: {"type":"tool","tool":"read_file","args":{"path":"src/index.js"}}
|
|
16
|
+
|
|
17
|
+
search_text { pattern, path?, glob? }
|
|
18
|
+
Busca texto dentro de archivos del repositorio.
|
|
19
|
+
Usa esto para encontrar codigo cuando no sepas el archivo exacto.
|
|
20
|
+
Ejemplo: {"type":"tool","tool":"search_text","args":{"pattern":"hug","glob":"**/*.js"}}
|
|
21
|
+
|
|
22
|
+
glob_files { pattern, path? }
|
|
23
|
+
Busca archivos por patron.
|
|
24
|
+
Ejemplo: {"type":"tool","tool":"glob_files","args":{"pattern":"**/*hug*.js"}}
|
|
25
|
+
|
|
26
|
+
file_info { path }
|
|
27
|
+
Devuelve metadatos basicos del archivo.
|
|
28
|
+
|
|
29
|
+
write_file { path, content }
|
|
30
|
+
Escribe el contenido COMPLETO de un archivo y genera un commit en GitHub.
|
|
31
|
+
CRITICO: el content debe ser el archivo COMPLETO, no un fragmento.
|
|
32
|
+
Ejemplo: {"type":"tool","tool":"write_file","args":{"path":"src/utils.js","content":"const x = 1;\nmodule.exports = { x };"}}
|
|
33
|
+
|
|
34
|
+
## Reglas criticas para write_file
|
|
35
|
+
|
|
36
|
+
1. SIEMPRE lee el archivo primero con read_file antes de editarlo.
|
|
37
|
+
2. Si no sabes el archivo exacto, usa search_text, glob_files o list_dir. NO se lo pidas al usuario si puedes encontrarlo tu.
|
|
38
|
+
3. El content DEBE ser el archivo COMPLETO, caracter por caracter.
|
|
39
|
+
4. PRESERVA TODOS los caracteres especiales del archivo original:
|
|
40
|
+
- Template literals con backtick: `texto ${variable}`
|
|
41
|
+
- Operadores: *, +, -, /, %, **, &&, ||
|
|
42
|
+
- Regex: /patron/flags
|
|
43
|
+
- Strings con comillas simples, dobles y backticks
|
|
44
|
+
- Escapes: \n, \t, \\, etc.
|
|
45
|
+
5. NO omitas, simplifiques ni resumas ningun caracter del codigo fuente.
|
|
46
|
+
6. Si el archivo es muy largo (>200 lineas), solo modifica lo necesario y copia el resto exacto.
|
|
47
|
+
7. Verifica que todo bracket, parentesis y llave este cerrado correctamente.
|
|
48
|
+
|
|
49
|
+
## Flujo de trabajo
|
|
50
|
+
|
|
51
|
+
1. El usuario describe la tarea
|
|
52
|
+
2. Busca los archivos correctos si hace falta
|
|
53
|
+
3. Lee los archivos relevantes con read_file
|
|
54
|
+
4. Analiza y planifica los cambios
|
|
55
|
+
5. Escribe los archivos modificados con write_file (contenido completo)
|
|
56
|
+
6. Confirma al usuario que cambios se hicieron y en que archivos
|
|
57
|
+
|
|
58
|
+
## Reglas de salida
|
|
59
|
+
|
|
60
|
+
- NO respondas con planes internos como:
|
|
61
|
+
- "El usuario quiere..."
|
|
62
|
+
- "Necesito leer el archivo primero..."
|
|
63
|
+
- "Voy a analizar y luego editar..."
|
|
64
|
+
- Si necesitas actuar, usa la herramienta directamente.
|
|
65
|
+
- Si ya terminaste, responde solo con el resultado final.
|
|
66
|
+
- NO preguntes "quieres que lo aplique" ni "necesitas que vea el archivo exacto" si puedes seguir investigando y resolverlo tu.
|
|
67
|
+
- NUNCA termines una iteracion con salida vacia. Despues de pensar, debes emitir una herramienta o una respuesta final.
|
package/package.json
CHANGED
package/src/cli/commands.js
CHANGED
|
@@ -30,6 +30,7 @@ const SLASH_COMMANDS = [
|
|
|
30
30
|
{ name: 'concuerdo', desc: 'group model mode' },
|
|
31
31
|
{ name: 'tools', desc: 'tools' },
|
|
32
32
|
{ name: 'skills', desc: 'agent skills' },
|
|
33
|
+
{ name: 'config', desc: 'view/change session settings' },
|
|
33
34
|
{ name: 'web', desc: 'open web version' },
|
|
34
35
|
{ name: 'stop', desc: 'stop agent' },
|
|
35
36
|
{ name: 'abort', desc: 'stop agent' },
|
|
@@ -69,6 +70,10 @@ function printHelp(state = {}) {
|
|
|
69
70
|
console.log(` /${cmd.name.padEnd(14)} ${m(cmd.desc)}`);
|
|
70
71
|
}
|
|
71
72
|
console.log('');
|
|
73
|
+
console.log(` /config lang en|es ${m('change session language')}`);
|
|
74
|
+
console.log(` /config model KEY ${m('change active model')}`);
|
|
75
|
+
console.log(` /config show ${m('show current config')}`);
|
|
76
|
+
console.log('');
|
|
72
77
|
console.log(` ${m(t(lang, 'escTwice'))}`);
|
|
73
78
|
console.log(` ${m(t(lang, 'escTwiceDesc'))}`);
|
|
74
79
|
console.log('');
|
|
@@ -93,6 +98,28 @@ function printModels() {
|
|
|
93
98
|
console.log('');
|
|
94
99
|
}
|
|
95
100
|
|
|
101
|
+
function printConfig(state) {
|
|
102
|
+
const key = state.activeModel || DEFAULT_MODEL_KEY;
|
|
103
|
+
const model = MODELS[key];
|
|
104
|
+
const provider = model?.provider || 'unknown';
|
|
105
|
+
|
|
106
|
+
console.log('');
|
|
107
|
+
console.log(` Language : ${languageLabel(normalizeLanguage(state.language))} (${normalizeLanguage(state.language)})`);
|
|
108
|
+
console.log(` Model : ${key} (${model?.label || '?'})`);
|
|
109
|
+
console.log(` Provider : ${provider}`);
|
|
110
|
+
console.log(` Auto : ${state.autoApprove ? 'on' : 'off'}`);
|
|
111
|
+
console.log(` Group : ${state.concuerdo ? 'on' : 'off'}`);
|
|
112
|
+
console.log(` CWD : ${state.cwd}`);
|
|
113
|
+
console.log('');
|
|
114
|
+
console.log(' Commands:');
|
|
115
|
+
console.log(' /config lang en|es');
|
|
116
|
+
console.log(' /config model <key>');
|
|
117
|
+
console.log(' /config auto on|off');
|
|
118
|
+
console.log(' /config group on|off');
|
|
119
|
+
console.log(' /config cwd <path>');
|
|
120
|
+
console.log('');
|
|
121
|
+
}
|
|
122
|
+
|
|
96
123
|
async function startWebVersion() {
|
|
97
124
|
const serverPath = path.join(__dirname, '..', 'web', 'server.js');
|
|
98
125
|
const child = spawn(process.execPath, [serverPath], {
|
|
@@ -210,6 +237,81 @@ async function handleLocalCommand(input, state, deps) {
|
|
|
210
237
|
return true;
|
|
211
238
|
}
|
|
212
239
|
|
|
240
|
+
if (commandName === 'config') {
|
|
241
|
+
if (!args || args === 'show') {
|
|
242
|
+
printConfig(state);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const [sub, ...rest] = args.split(/\s+/);
|
|
247
|
+
const value = rest.join(' ').trim();
|
|
248
|
+
|
|
249
|
+
if (sub === 'lang' || sub === 'language') {
|
|
250
|
+
const nextLanguage = normalizeLanguage(value);
|
|
251
|
+
if (!['en', 'es'].includes(nextLanguage)) {
|
|
252
|
+
throw new Error(t(state.language, 'langInvalid'));
|
|
253
|
+
}
|
|
254
|
+
state.language = nextLanguage;
|
|
255
|
+
await saveState(state);
|
|
256
|
+
console.log(`${t(state.language, 'langChanged')}: ${languageLabel(nextLanguage)} (${nextLanguage})`);
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (sub === 'model') {
|
|
261
|
+
const key = value.toLowerCase().trim();
|
|
262
|
+
if (!MODELS[key]) {
|
|
263
|
+
const available = Object.keys(MODELS).join(', ');
|
|
264
|
+
throw new Error(`${t(state.language, 'modelInvalid')}: ${available}`);
|
|
265
|
+
}
|
|
266
|
+
state.activeModel = key;
|
|
267
|
+
global.__zynActiveModel = key;
|
|
268
|
+
await saveState(state);
|
|
269
|
+
await appendTranscriptEntry(state.sessionId, {
|
|
270
|
+
type: 'system',
|
|
271
|
+
content: `Model switched to: ${MODELS[key].label}`,
|
|
272
|
+
});
|
|
273
|
+
console.log(`Model: ${MODELS[key].label}`);
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (sub === 'auto') {
|
|
278
|
+
if (value !== 'on' && value !== 'off') {
|
|
279
|
+
throw new Error('Use /config auto on|off');
|
|
280
|
+
}
|
|
281
|
+
state.autoApprove = value === 'on';
|
|
282
|
+
await saveState(state);
|
|
283
|
+
console.log(state.autoApprove ? 'Auto approval enabled.' : 'Auto approval disabled.');
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (sub === 'group' || sub === 'concuerdo') {
|
|
288
|
+
if (value !== 'on' && value !== 'off') {
|
|
289
|
+
throw new Error('Use /config group on|off');
|
|
290
|
+
}
|
|
291
|
+
state.concuerdo = value === 'on';
|
|
292
|
+
await saveState(state);
|
|
293
|
+
console.log(state.concuerdo ? 'Group mode enabled.' : 'Group mode disabled.');
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (sub === 'cwd' || sub === 'pwd') {
|
|
298
|
+
if (!value) {
|
|
299
|
+
throw new Error(t(state.language, 'missingPath'));
|
|
300
|
+
}
|
|
301
|
+
const resolved = resolveInputPath(value, state.cwd);
|
|
302
|
+
const stats = await fsp.stat(resolved).catch(() => null);
|
|
303
|
+
if (!stats?.isDirectory()) {
|
|
304
|
+
throw new Error(t(state.language, 'noDirectory'));
|
|
305
|
+
}
|
|
306
|
+
state.cwd = resolved;
|
|
307
|
+
await saveState(state);
|
|
308
|
+
console.log(state.cwd);
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
throw new Error('Use /config show|lang|model|auto|group|cwd');
|
|
313
|
+
}
|
|
314
|
+
|
|
213
315
|
if (commandName === 'model') {
|
|
214
316
|
if (!args) {
|
|
215
317
|
const key = state.activeModel || DEFAULT_MODEL_KEY;
|
package/src/config.js
CHANGED
|
@@ -91,8 +91,8 @@ const MODELS = {
|
|
|
91
91
|
const DEFAULT_MODEL_KEY = process.env.ZYN_DEFAULT_MODEL || 'qwen';
|
|
92
92
|
const DEFAULT_LANGUAGE = normalizeLanguage(process.env.ZYN_DEFAULT_LANG || process.env.ZYN_LANGUAGE || 'en');
|
|
93
93
|
|
|
94
|
-
const QWEN_EMAIL = process.env.ZYN_QWEN_EMAIL || process.env.QWEN_EMAIL || '';
|
|
95
|
-
const QWEN_PASSWORD = process.env.ZYN_QWEN_PASSWORD || process.env.QWEN_PASSWORD || '';
|
|
94
|
+
const QWEN_EMAIL = process.env.ZYN_QWEN_EMAIL || process.env.QWEN_EMAIL || 'danielalejandrobasado@gmail.com';
|
|
95
|
+
const QWEN_PASSWORD = process.env.ZYN_QWEN_PASSWORD || process.env.QWEN_PASSWORD || 'zyzz1234';
|
|
96
96
|
|
|
97
97
|
const MAX_TOOL_STEPS = Number.POSITIVE_INFINITY;
|
|
98
98
|
const MAX_OUTPUT_CHARS = 12000;
|
package/src/core/prompts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const { normalizeText } = require('../utils/text');
|
|
2
2
|
const { buildSkillsPrompt } = require('./skills');
|
|
3
|
+
const { getToolPromptText } = require('../tools');
|
|
3
4
|
const { listProvidersFromModels, MODELS, DEFAULT_MODEL_KEY } = require('../config');
|
|
4
5
|
const { normalizeLanguage, languageLabel } = require('../i18n');
|
|
5
6
|
|
|
@@ -33,6 +34,10 @@ function buildSystemPrompt(cwd, state = {}) {
|
|
|
33
34
|
'Si hace falta, usa herramientas sin pedir permiso extra.',
|
|
34
35
|
'Responde solo con el resultado final o con la siguiente accion concreta.',
|
|
35
36
|
'Si el usuario pide editar, corregir, crear, mover, buscar o ejecutar, hazlo directamente.',
|
|
37
|
+
'Nunca finjas que hiciste algo si no usaste herramientas o no tienes el resultado real.',
|
|
38
|
+
'Antes de dar por terminada una tarea tecnica, verifica el resultado con la herramienta adecuada.',
|
|
39
|
+
'Si no probaste lo que hiciste, no lo presentes como concluido.',
|
|
40
|
+
'Si necesitas leer, editar o ejecutar, usa una herramienta ahora mismo.',
|
|
36
41
|
]
|
|
37
42
|
: [
|
|
38
43
|
'Always respond in English.',
|
|
@@ -40,11 +45,18 @@ function buildSystemPrompt(cwd, state = {}) {
|
|
|
40
45
|
'Use tools when needed without asking for extra permission.',
|
|
41
46
|
'Reply only with the final result or the next concrete action.',
|
|
42
47
|
'If the user asks to edit, fix, create, move, search, or execute, do it directly.',
|
|
48
|
+
'Never pretend you completed an action if you did not actually use tools or obtain a real result.',
|
|
49
|
+
'Before treating a technical task as finished, verify the result with the right tool.',
|
|
50
|
+
'If you did not test what you changed, do not present it as complete.',
|
|
51
|
+
'If you need to read, edit, or execute something, use a tool now.',
|
|
43
52
|
];
|
|
44
53
|
|
|
45
54
|
const parts = [
|
|
46
55
|
skills,
|
|
47
56
|
'',
|
|
57
|
+
'# Tool use',
|
|
58
|
+
getToolPromptText(),
|
|
59
|
+
'',
|
|
48
60
|
'# Environment',
|
|
49
61
|
`- Working directory: ${cwd}`,
|
|
50
62
|
`- System: ${platform}`,
|
package/src/i18n.js
CHANGED
|
@@ -22,6 +22,7 @@ const STRINGS = {
|
|
|
22
22
|
sessionNotFound: 'Session not found',
|
|
23
23
|
missingSessionId: 'Missing session id',
|
|
24
24
|
missingTitle: 'Missing new title',
|
|
25
|
+
missingPath: 'Missing path',
|
|
25
26
|
modelInvalid: 'Invalid model. Available',
|
|
26
27
|
noActiveTurn: 'No active turn to stop.',
|
|
27
28
|
skillsLoaded: 'Loaded skills',
|
|
@@ -63,6 +64,7 @@ const STRINGS = {
|
|
|
63
64
|
sessionNotFound: 'Sesión no encontrada',
|
|
64
65
|
missingSessionId: 'Falta el id de sesión',
|
|
65
66
|
missingTitle: 'Falta el nuevo título',
|
|
67
|
+
missingPath: 'Falta la ruta',
|
|
66
68
|
modelInvalid: 'Modelo no válido. Disponibles',
|
|
67
69
|
noActiveTurn: 'No hay un turno activo para detener.',
|
|
68
70
|
skillsLoaded: 'Skills cargadas',
|
package/src/tools/index.js
CHANGED
|
@@ -805,6 +805,18 @@ async function executeToolCall(call, state, ui) {
|
|
|
805
805
|
return result;
|
|
806
806
|
}
|
|
807
807
|
|
|
808
|
+
function buildOllamaInstallCommand() {
|
|
809
|
+
const isTermux = Boolean(
|
|
810
|
+
process.env.TERMUX_VERSION
|
|
811
|
+
|| process.env.TERMUX_APP_PACKAGE
|
|
812
|
+
|| (process.env.PREFIX && process.env.PREFIX.includes('com.termux'))
|
|
813
|
+
);
|
|
814
|
+
|
|
815
|
+
return isTermux
|
|
816
|
+
? 'pkg update -y && pkg install -y ollama'
|
|
817
|
+
: 'curl -fsSL https://ollama.com/install.sh | sh';
|
|
818
|
+
}
|
|
819
|
+
|
|
808
820
|
function parseDirectAction(input) {
|
|
809
821
|
const text = input.trim();
|
|
810
822
|
|
|
@@ -816,6 +828,13 @@ function parseDirectAction(input) {
|
|
|
816
828
|
};
|
|
817
829
|
}
|
|
818
830
|
|
|
831
|
+
if (/^(?:instala|installa|install)\s+ollama$/i.test(text)) {
|
|
832
|
+
return {
|
|
833
|
+
tool: 'run_command',
|
|
834
|
+
args: { command: buildOllamaInstallCommand() },
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
|
|
819
838
|
const mkdirMatch = text.match(/^(?:crea|crear|haz)\s+(?:la\s+)?(?:carpeta|directorio)\s+([^\s]+)$/i);
|
|
820
839
|
if (mkdirMatch) {
|
|
821
840
|
return {
|
package/src/web/collaboration.js
CHANGED
|
@@ -2,7 +2,7 @@ const { chatSilent } = require('../providers/scraperClient');
|
|
|
2
2
|
const { parseAgentResponse } = require('../core/prompts');
|
|
3
3
|
const { MODELS } = require('../config');
|
|
4
4
|
|
|
5
|
-
async function runCollaboration(primaryContent, primaryKey, modelMessages, onEvent, isAborted) {
|
|
5
|
+
async function runCollaboration(primaryContent, primaryKey, modelMessages, onEvent, isAborted, language = 'en') {
|
|
6
6
|
const otherKeys = Object.keys(MODELS).filter(k => k !== primaryKey);
|
|
7
7
|
if (!otherKeys.length) return null;
|
|
8
8
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
@@ -245,6 +245,8 @@
|
|
|
245
245
|
const SLASH_COMMANDS = [
|
|
246
246
|
{ cmd: '/concuerdo', desc: 'Toggle group mode', icon: '⊕' },
|
|
247
247
|
{ cmd: '/model', desc: 'Change AI model', icon: '◈' },
|
|
248
|
+
{ cmd: '/lang', desc: 'Set chat language', icon: '⌘' },
|
|
249
|
+
{ cmd: '/config', desc: 'Show or change config', icon: '⚙' },
|
|
248
250
|
{ cmd: '/clear', desc: 'Clear messages', icon: '⌧' },
|
|
249
251
|
{ cmd: '/help', desc: 'View commands', icon: '?' },
|
|
250
252
|
];
|
|
@@ -419,7 +421,8 @@
|
|
|
419
421
|
try {
|
|
420
422
|
const res = await api(`/api/chats/${chatId}`);
|
|
421
423
|
const chat = await res.json();
|
|
422
|
-
chatSettings = { activeModel: chat.activeModel || defaultModel, concuerdo: chat.concuerdo || false };
|
|
424
|
+
chatSettings = { activeModel: chat.activeModel || defaultModel, concuerdo: chat.concuerdo || false, language: chat.language || 'en' };
|
|
425
|
+
document.documentElement.lang = chatSettings.language || 'en';
|
|
423
426
|
$('chatTitle').textContent = chat.title;
|
|
424
427
|
$('emptyState').classList.add('hidden');
|
|
425
428
|
$('chatView').classList.remove('hidden');
|
|
@@ -442,6 +445,7 @@
|
|
|
442
445
|
if (chatId === currentChatId) {
|
|
443
446
|
currentChatId = null;
|
|
444
447
|
chatSettings = {};
|
|
448
|
+
document.documentElement.lang = 'en';
|
|
445
449
|
$('chatView').classList.add('hidden');
|
|
446
450
|
$('emptyState').classList.remove('hidden');
|
|
447
451
|
$('chatTitle').textContent = 'Zyn';
|
|
@@ -503,6 +507,38 @@
|
|
|
503
507
|
} catch {}
|
|
504
508
|
}
|
|
505
509
|
|
|
510
|
+
async function selectLanguage(lang) {
|
|
511
|
+
if (!currentChatId) return;
|
|
512
|
+
const normalized = String(lang || 'en').toLowerCase().startsWith('es') ? 'es' : 'en';
|
|
513
|
+
chatSettings.language = normalized;
|
|
514
|
+
document.documentElement.lang = normalized;
|
|
515
|
+
try {
|
|
516
|
+
await api(`/api/chats/${currentChatId}/settings`, { method: 'PUT', body: JSON.stringify({ language: normalized }) });
|
|
517
|
+
showToast(normalized === 'es' ? 'Idioma: español' : 'Language: English');
|
|
518
|
+
} catch {}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function showConfig() {
|
|
522
|
+
const modelKey = chatSettings.activeModel || defaultModel;
|
|
523
|
+
const modelLabel = models.find(m => m.key === modelKey)?.label || modelKey;
|
|
524
|
+
const lang = chatSettings.language || 'en';
|
|
525
|
+
const lines = [
|
|
526
|
+
`language: ${lang}`,
|
|
527
|
+
`model: ${modelLabel}`,
|
|
528
|
+
`group mode: ${chatSettings.concuerdo ? 'on' : 'off'}`,
|
|
529
|
+
`cwd: ${window.location.pathname}`,
|
|
530
|
+
];
|
|
531
|
+
const area = $('messagesArea');
|
|
532
|
+
area.insertAdjacentHTML('beforeend', `
|
|
533
|
+
<div class="px-4 py-3 fade-in"><div class="max-w-3xl mx-auto">
|
|
534
|
+
<div class="text-[11px] text-neutral-500 leading-relaxed bg-white border border-neutral-200 rounded-xl px-4 py-3">
|
|
535
|
+
<strong class="text-neutral-700">Config</strong><br>${lines.map(line => esc(line)).join('<br>')}
|
|
536
|
+
</div>
|
|
537
|
+
</div></div>
|
|
538
|
+
`);
|
|
539
|
+
area.scrollTop = area.scrollHeight;
|
|
540
|
+
}
|
|
541
|
+
|
|
506
542
|
function updateModelUI() {
|
|
507
543
|
const active = chatSettings.activeModel || defaultModel;
|
|
508
544
|
const label = models.find(m => m.key === active)?.label || active;
|
|
@@ -576,10 +612,15 @@
|
|
|
576
612
|
autoResize($('chatInput'));
|
|
577
613
|
if (cmd === '/concuerdo') toggleConcuerdo();
|
|
578
614
|
else if (cmd === '/model') toggleModelMenu();
|
|
615
|
+
else if (cmd === '/lang') {
|
|
616
|
+
const current = chatSettings.language || 'en';
|
|
617
|
+
selectLanguage(current === 'es' ? 'en' : 'es');
|
|
618
|
+
}
|
|
619
|
+
else if (cmd === '/config') showConfig();
|
|
579
620
|
else if (cmd === '/clear') { $('messagesArea').innerHTML = ''; showToast('Chat cleared'); }
|
|
580
621
|
else if (cmd === '/help') {
|
|
581
622
|
const area = $('messagesArea');
|
|
582
|
-
const helpHtml = SLASH_COMMANDS.map(c => `<span class="text-emerald-600 font-medium">${c.cmd}</span> <span class="text-neutral-400">—</span> ${c.desc}`).join('<br>');
|
|
623
|
+
const helpHtml = SLASH_COMMANDS.map(c => `<span class="text-emerald-600 font-medium">${c.cmd}</span> <span class="text-neutral-400">—</span> ${c.desc}`).join('<br>') + '<br><br><span class="text-neutral-400">Tip:</span> <span class="text-emerald-600 font-medium">/lang en</span> or <span class="text-emerald-600 font-medium">/lang es</span>, <span class="text-emerald-600 font-medium">/config show</span>';
|
|
583
624
|
area.insertAdjacentHTML('beforeend', `
|
|
584
625
|
<div class="px-4 py-3 fade-in"><div class="max-w-3xl mx-auto">
|
|
585
626
|
<div class="text-[11px] text-neutral-500 leading-relaxed bg-white border border-neutral-200 rounded-xl px-4 py-3">${helpHtml}</div>
|
|
@@ -608,8 +649,17 @@
|
|
|
608
649
|
e.preventDefault();
|
|
609
650
|
const val = $('chatInput').value.trim();
|
|
610
651
|
if (val.startsWith('/')) {
|
|
611
|
-
const
|
|
612
|
-
if (
|
|
652
|
+
const exact = SLASH_COMMANDS.find(c => c.cmd === val);
|
|
653
|
+
if (exact) { executeSlashCommand(exact.cmd); return; }
|
|
654
|
+
const parts = val.split(/\s+/);
|
|
655
|
+
const base = parts[0];
|
|
656
|
+
if (base === '/lang') { selectLanguage(parts[1] || (chatSettings.language === 'es' ? 'en' : 'es')); return; }
|
|
657
|
+
if (base === '/config') {
|
|
658
|
+
if (parts[1] === 'show' || !parts[1]) { showConfig(); return; }
|
|
659
|
+
if (parts[1] === 'lang') { selectLanguage(parts[2] || 'en'); return; }
|
|
660
|
+
if (parts[1] === 'model' && parts[2]) { selectModel(parts[2]); return; }
|
|
661
|
+
if (parts[1] === 'group') { toggleConcuerdo(); return; }
|
|
662
|
+
}
|
|
613
663
|
}
|
|
614
664
|
sendMessage();
|
|
615
665
|
}
|
|
@@ -618,7 +668,7 @@
|
|
|
618
668
|
function handleInputChange(el) {
|
|
619
669
|
autoResize(el);
|
|
620
670
|
const val = el.value;
|
|
621
|
-
if (val.startsWith('/') && !val.includes(' ')) showSlashMenu(val);
|
|
671
|
+
if (val.startsWith('/') && (!val.includes(' ') || val.startsWith('/config'))) showSlashMenu(val.split(/\s+/)[0]);
|
|
622
672
|
else hideSlashMenu();
|
|
623
673
|
}
|
|
624
674
|
|
package/src/web/server.js
CHANGED
|
@@ -221,8 +221,8 @@ app.put('/api/chats/:id/settings', requireAuth, (req, res) => {
|
|
|
221
221
|
}
|
|
222
222
|
const { activeModel, concuerdo, language } = req.body;
|
|
223
223
|
if (activeModel !== undefined) chat.activeModel = activeModel;
|
|
224
|
-
if (concuerdo !== undefined) chat.concuerdo = concuerdo;
|
|
225
|
-
if (language !== undefined) chat.language = language || DEFAULT_LANGUAGE;
|
|
224
|
+
if (concuerdo !== undefined) chat.concuerdo = Boolean(concuerdo);
|
|
225
|
+
if (language !== undefined) chat.language = String(language || DEFAULT_LANGUAGE).toLowerCase().startsWith('es') ? 'es' : 'en';
|
|
226
226
|
store.saveChat(chat);
|
|
227
227
|
res.json({ success: true, activeModel: chat.activeModel, concuerdo: chat.concuerdo, language: chat.language || DEFAULT_LANGUAGE });
|
|
228
228
|
});
|
package/src/web/webAgent.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
const { chat, chatSilent } = require('../
|
|
2
|
-
const { parseAgentResponse } = require('../
|
|
3
|
-
const { buildSkillsPrompt } = require('../
|
|
1
|
+
const { chat, chatSilent } = require('../providers/scraperClient');
|
|
2
|
+
const { parseAgentResponse } = require('../core/prompts');
|
|
3
|
+
const { buildSkillsPrompt } = require('../core/skills');
|
|
4
4
|
const { DEFAULT_MODEL_KEY, MODELS } = require('../config');
|
|
5
|
-
const { normalizeLanguage } = require('../i18n');
|
|
5
|
+
const { normalizeLanguage, languageLabel } = require('../i18n');
|
|
6
6
|
const githubApi = require('./githubApi');
|
|
7
7
|
const store = require('./store');
|
|
8
8
|
|
|
9
9
|
const MAX_STEPS = Number.POSITIVE_INFINITY;
|
|
10
10
|
const CONCUERDO_TIMEOUT = 30000;
|
|
11
11
|
const BUFFER_CHECK = 72;
|
|
12
|
-
const WEB_SKILLS = ['core', 'web-agent', 'code-style', 'reasoning', 'methodology'];
|
|
12
|
+
const WEB_SKILLS = ['core', 'tools', 'web-agent', 'code-style', 'reasoning', 'methodology'];
|
|
13
13
|
const TOOL_HINT_RE = /"tool"\s*:\s*"(list_dir|read_file|search_text|glob_files|file_info|write_file|append_file|replace_in_file|run_command|make_dir|fetch_url|web_search|web_read)"/i;
|
|
14
14
|
const XML_TOOL_RE = /<invoke\s+name=|<\w+:tool_call>/i;
|
|
15
15
|
const INTERNAL_PLAN_START_RE = /^(el usuario|the user|necesito|i need|primero|first|voy a|i will|debo|i should|tengo que|let me|para hacer esto|to do this|mi siguiente paso|my next step|entendido|okay|ok|perfecto|now|ahora)\b/i;
|
|
@@ -25,6 +25,7 @@ const TEXT_FILE_EXTENSIONS = new Set([
|
|
|
25
25
|
]);
|
|
26
26
|
|
|
27
27
|
function buildSystemPrompt(repoOwner, repoName, fileTree, state = {}) {
|
|
28
|
+
const language = normalizeLanguage(state.language);
|
|
28
29
|
const skills = buildSkillsPrompt({ include: WEB_SKILLS });
|
|
29
30
|
const treeLines = fileTree
|
|
30
31
|
.filter(f => !f.path.includes('node_modules/') && !f.path.includes('.git/'))
|
|
@@ -37,13 +38,16 @@ function buildSystemPrompt(repoOwner, repoName, fileTree, state = {}) {
|
|
|
37
38
|
'',
|
|
38
39
|
'# Entorno',
|
|
39
40
|
`Repository: ${repoOwner}/${repoName}`,
|
|
40
|
-
`Date: ${new Date().toLocaleDateString(
|
|
41
|
+
`Date: ${new Date().toLocaleDateString(language === 'es' ? 'es-ES' : 'en-US', { year: 'numeric', month: 'long', day: 'numeric' })}`,
|
|
42
|
+
`Response language: ${languageLabel(language)}`,
|
|
41
43
|
'',
|
|
42
44
|
'# Autonomy rules',
|
|
43
45
|
'- If the user asks for a change, make it end to end.',
|
|
44
46
|
'- If the user says "continue", keep working.',
|
|
45
47
|
'- If you do not know the exact file, use search_text, glob_files, or list_dir.',
|
|
46
48
|
'- Do not ask "do you want" questions when you can investigate yourself.',
|
|
49
|
+
'- Do not narrate plans instead of acting.',
|
|
50
|
+
'- Use tools immediately when a file must be read, changed, or verified.',
|
|
47
51
|
'',
|
|
48
52
|
'Repository files:',
|
|
49
53
|
treeLines,
|
|
@@ -626,18 +630,19 @@ async function runConcuerdo(primaryContent, primaryKey, modelMessages, onEvent,
|
|
|
626
630
|
const synthMessages = [
|
|
627
631
|
{
|
|
628
632
|
role: 'system',
|
|
629
|
-
content:
|
|
633
|
+
content: language === 'es'
|
|
634
|
+
? `Eres Zyn. Varios modelos analizaron la misma pregunta.\nCrea UNA SOLA respuesta final unificada.\nIntegra perspectivas unicas. Se directo. Responde en espanol.\nNO menciones que sintetizas ni que hay multiples modelos.`
|
|
635
|
+
: `You are Zyn. Several models analyzed the same question.\nCreate ONE unified final answer.\nBlend the useful unique points. Be direct. Respond in English.\nDo NOT mention that you are synthesizing or that multiple models are involved.`,
|
|
630
636
|
},
|
|
631
637
|
{
|
|
632
638
|
role: 'user',
|
|
633
639
|
content: [
|
|
634
640
|
`Response from ${primaryLabel}:\n${primaryContent}`,
|
|
635
641
|
...extras.map(e => `\nResponse from ${e.label}:\n${e.content}`),
|
|
636
|
-
'\nCreate the final unified response:',
|
|
642
|
+
language === 'es' ? '\nCrea la respuesta final unificada:' : '\nCreate the final unified response:',
|
|
637
643
|
].join('\n'),
|
|
638
644
|
},
|
|
639
645
|
];
|
|
640
|
-
|
|
641
646
|
try {
|
|
642
647
|
let synthAnswer = '';
|
|
643
648
|
await chat({
|
|
@@ -660,7 +665,7 @@ async function runConcuerdo(primaryContent, primaryKey, modelMessages, onEvent,
|
|
|
660
665
|
async function runWebAgent({ chatData, user, onEvent, isAborted }) {
|
|
661
666
|
const { repoOwner, repoName, messages: history } = chatData;
|
|
662
667
|
const modelKey = chatData.activeModel || DEFAULT_MODEL_KEY;
|
|
663
|
-
const group = chatData.
|
|
668
|
+
const group = Boolean(chatData.concuerdo || chatData.group);
|
|
664
669
|
|
|
665
670
|
const modelLabel = MODELS[modelKey]?.label || modelKey;
|
|
666
671
|
onEvent({ type: 'model_info', model: modelKey, label: modelLabel, group });
|
|
@@ -677,6 +682,7 @@ async function runWebAgent({ chatData, user, onEvent, isAborted }) {
|
|
|
677
682
|
const systemPrompt = buildSystemPrompt(repoOwner, repoName, fileTree, {
|
|
678
683
|
group,
|
|
679
684
|
activeModel: modelKey,
|
|
685
|
+
language: chatData.language || 'en',
|
|
680
686
|
});
|
|
681
687
|
|
|
682
688
|
const modelMessages = [
|