xonecode 0.8.46 → 0.11.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 (147) hide show
  1. package/THIRD_PARTY_NOTICES.md +56 -0
  2. package/apps/web/dist/assets/index-BAyybSz-.css +1 -0
  3. package/apps/web/dist/assets/index-BNCMVjWv.js +485 -0
  4. package/apps/web/dist/assets/{php-Bx1jVads.js → php-DPbDT8rX.js} +1 -1
  5. package/apps/web/dist/assets/{ruby-L0I9KR6K.js → ruby-Bfvws9R8.js} +1 -1
  6. package/apps/web/dist/index.html +2 -2
  7. package/apps/web/dist/openui/visor.css +1 -0
  8. package/apps/web/dist/openui/visor.js +9113 -0
  9. package/dist/agent/exportarPdf.js +5 -1
  10. package/dist/agent/exportarPdf.js.map +1 -1
  11. package/dist/agent/grafo/arbolDeProyecto.js +67 -2
  12. package/dist/agent/grafo/arbolDeProyecto.js.map +1 -1
  13. package/dist/agent/grafo/memoriaDeProyecto.js +3 -2
  14. package/dist/agent/grafo/memoriaDeProyecto.js.map +1 -1
  15. package/dist/agent/grafo/navegacionXone.js +8 -3
  16. package/dist/agent/grafo/navegacionXone.js.map +1 -1
  17. package/dist/agent/grafo/opcionesDeFicheros.js +24 -0
  18. package/dist/agent/grafo/opcionesDeFicheros.js.map +1 -0
  19. package/dist/agent/grafo/perfiles.js +1 -1
  20. package/dist/agent/grafo/perfiles.js.map +1 -1
  21. package/dist/agent/grafo/proyecto.js +31 -15
  22. package/dist/agent/grafo/proyecto.js.map +1 -1
  23. package/dist/agent/grafo/unirSecciones.js +128 -0
  24. package/dist/agent/grafo/unirSecciones.js.map +1 -0
  25. package/dist/agent/grafo/xoneAgent.js +56 -51
  26. package/dist/agent/grafo/xoneAgent.js.map +1 -1
  27. package/dist/agent/motores/trueforge/capacidades.js +179 -0
  28. package/dist/agent/motores/trueforge/capacidades.js.map +1 -0
  29. package/dist/agent/motores/trueforge/eventosTrueforge.js +143 -0
  30. package/dist/agent/motores/trueforge/eventosTrueforge.js.map +1 -0
  31. package/dist/agent/motores/trueforge/memoriaTrueforge.js +336 -0
  32. package/dist/agent/motores/trueforge/memoriaTrueforge.js.map +1 -0
  33. package/dist/agent/motores/trueforge/metricasTrueforge.js +55 -0
  34. package/dist/agent/motores/trueforge/metricasTrueforge.js.map +1 -0
  35. package/dist/agent/motores/trueforge/modeloExterno.js +46 -0
  36. package/dist/agent/motores/trueforge/modeloExterno.js.map +1 -0
  37. package/dist/agent/motores/trueforge/modeloLangchain.js +152 -0
  38. package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -0
  39. package/dist/agent/motores/trueforge/recortes.js +121 -0
  40. package/dist/agent/motores/trueforge/recortes.js.map +1 -0
  41. package/dist/agent/motores/trueforge/sesionTrueforge.js +1062 -0
  42. package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -0
  43. package/dist/agent/motores/trueforge/skillsTrueforge.js +14 -0
  44. package/dist/agent/motores/trueforge/skillsTrueforge.js.map +1 -0
  45. package/dist/agent/motores/trueforge/toolsDeFichero.js +265 -0
  46. package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -0
  47. package/dist/agent/motores/trueforge/toolsPropias.js +65 -0
  48. package/dist/agent/motores/trueforge/toolsPropias.js.map +1 -0
  49. package/dist/agent/motores/trueforge/trueforge.js +45 -0
  50. package/dist/agent/motores/trueforge/trueforge.js.map +1 -0
  51. package/dist/agent/navegacion/indiceEnDisco.js +10 -1
  52. package/dist/agent/navegacion/indiceEnDisco.js.map +1 -1
  53. package/dist/agent/planesEnDisco.js +64 -0
  54. package/dist/agent/planesEnDisco.js.map +1 -0
  55. package/dist/agent/sesiones/memoriaDeHilo.js +24 -0
  56. package/dist/agent/sesiones/memoriaDeHilo.js.map +1 -0
  57. package/dist/agent/sesiones/modeloDelCambio.js +70 -0
  58. package/dist/agent/sesiones/modeloDelCambio.js.map +1 -0
  59. package/dist/agent/sesiones/sesionGit.js +14 -0
  60. package/dist/agent/sesiones/sesionGit.js.map +1 -1
  61. package/dist/agent/subagentes/actividadDeCodex.js +60 -0
  62. package/dist/agent/subagentes/actividadDeCodex.js.map +1 -0
  63. package/dist/agent/subagentes/agentesEnDisco.js +95 -5
  64. package/dist/agent/subagentes/agentesEnDisco.js.map +1 -1
  65. package/dist/agent/subagentes/escrituraExterna.js +10 -2
  66. package/dist/agent/subagentes/escrituraExterna.js.map +1 -1
  67. package/dist/agent/subagentes/subagenteCodex.js +20 -0
  68. package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
  69. package/dist/agent/subagentes/subagenteExterno.js +269 -202
  70. package/dist/agent/subagentes/subagenteExterno.js.map +1 -1
  71. package/dist/agent/subagentes/subagenteOpencode.js +19 -2
  72. package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
  73. package/dist/agent/turno/diagnosticoDeTools.js +3 -0
  74. package/dist/agent/turno/diagnosticoDeTools.js.map +1 -1
  75. package/dist/agent/turno/ficherosDelProyecto.js +62 -0
  76. package/dist/agent/turno/ficherosDelProyecto.js.map +1 -0
  77. package/dist/agent/turno/informeDeTraza.js +28 -1
  78. package/dist/agent/turno/informeDeTraza.js.map +1 -1
  79. package/dist/agent/turno/puente.js +17 -1
  80. package/dist/agent/turno/puente.js.map +1 -1
  81. package/dist/agent/turno/resumenDeContexto.js +17 -4
  82. package/dist/agent/turno/resumenDeContexto.js.map +1 -1
  83. package/dist/agent/turno/resumenDeTool.js +3 -0
  84. package/dist/agent/turno/resumenDeTool.js.map +1 -1
  85. package/dist/agent/turno/sesionReal.js +2 -0
  86. package/dist/agent/turno/sesionReal.js.map +1 -0
  87. package/dist/agent/turno/turnoReal.js +55 -164
  88. package/dist/agent/turno/turnoReal.js.map +1 -1
  89. package/dist/agent/turno/verificacion.js +142 -0
  90. package/dist/agent/turno/verificacion.js.map +1 -0
  91. package/dist/cli/config.js +19 -0
  92. package/dist/cli/config.js.map +1 -1
  93. package/dist/cli/consola.js.map +1 -1
  94. package/dist/cli/main.js +35 -2
  95. package/dist/cli/main.js.map +1 -1
  96. package/dist/cli/tui/correrTui.js +1 -1
  97. package/dist/cli/tui/correrTui.js.map +1 -1
  98. package/dist/cli/tui/transcript.js +9 -0
  99. package/dist/cli/tui/transcript.js.map +1 -1
  100. package/dist/core/actos.js.map +1 -1
  101. package/dist/core/agentes.js +17 -0
  102. package/dist/core/agentes.js.map +1 -1
  103. package/dist/core/artefactos.js +22 -0
  104. package/dist/core/artefactos.js.map +1 -1
  105. package/dist/core/config.js +13 -0
  106. package/dist/core/config.js.map +1 -1
  107. package/dist/core/diffDeColecciones.js +84 -0
  108. package/dist/core/diffDeColecciones.js.map +1 -0
  109. package/dist/core/exportacion.js +6 -1
  110. package/dist/core/exportacion.js.map +1 -1
  111. package/dist/core/fotoDeColecciones.js +48 -0
  112. package/dist/core/fotoDeColecciones.js.map +1 -0
  113. package/dist/core/imagenesDeDocumento.js +88 -0
  114. package/dist/core/imagenesDeDocumento.js.map +1 -0
  115. package/dist/core/memoria.js +24 -0
  116. package/dist/core/memoria.js.map +1 -0
  117. package/dist/core/motor.js +41 -0
  118. package/dist/core/motor.js.map +1 -0
  119. package/dist/core/navegacion.js.map +1 -1
  120. package/dist/core/notify.js +23 -5
  121. package/dist/core/notify.js.map +1 -1
  122. package/dist/core/ports.js.map +1 -1
  123. package/dist/core/serieDeEscrituras.js +13 -0
  124. package/dist/core/serieDeEscrituras.js.map +1 -1
  125. package/dist/core/settings.js +17 -1
  126. package/dist/core/settings.js.map +1 -1
  127. package/dist/core/tareasDelPlan.js +103 -0
  128. package/dist/core/tareasDelPlan.js.map +1 -0
  129. package/dist/core/trazaDeErrores.js +42 -3
  130. package/dist/core/trazaDeErrores.js.map +1 -1
  131. package/dist/core/turno.js +44 -4
  132. package/dist/core/turno.js.map +1 -1
  133. package/dist/web/servidor/arranque.js +204 -5
  134. package/dist/web/servidor/arranque.js.map +1 -1
  135. package/dist/web/servidor/pielWeb.js +69 -4
  136. package/dist/web/servidor/pielWeb.js.map +1 -1
  137. package/dist/web/servidor/sesiones.js +11 -0
  138. package/dist/web/servidor/sesiones.js.map +1 -1
  139. package/dist/web/servidor/transporte.js.map +1 -1
  140. package/dist/web/servidor/vestibulo.js +23 -2
  141. package/dist/web/servidor/vestibulo.js.map +1 -1
  142. package/dist/web/servidor/visorOpenui.js +63 -0
  143. package/dist/web/servidor/visorOpenui.js.map +1 -0
  144. package/package.json +7 -2
  145. package/skills/openui-builder/SKILL.md +48 -0
  146. package/apps/web/dist/assets/index-GRwyotMV.js +0 -478
  147. package/apps/web/dist/assets/index-_cBVqq54.css +0 -1
@@ -0,0 +1,336 @@
1
+ /**
2
+ * La memoria de una conversación de TrueForge, en disco: la FOTO del hilo raíz.
3
+ *
4
+ * Sin esto el árbol de hilos vivía en memoria y reabrir una sesión de este motor empezaba de
5
+ * cero, con la interfaz enseñando la conversación de antes como si el modelo la recordara.
6
+ *
7
+ * **Es la foto del RAÍZ, no la capa `agent-session` de TrueForge, y es a propósito.** Esa capa
8
+ * trae su propio registro de sesiones, turnos y eventos —un segundo índice al lado del nuestro,
9
+ * con su propio «de quién es esto»— y su factoría de subagentes SUSTITUYE el primer mensaje del
10
+ * hijo por el encargo pelado. Lo que hace falta para «reabrir continúa» es menos:
11
+ * `AgentThread.toSnapshot()` y su constructor, que aceptan el contexto de vuelta. Los hijos mueren
12
+ * con su turno por diseño, así que no hay nada suyo que guardar.
13
+ *
14
+ * Tres reglas, las mismas que el checkpoint de deepagents:
15
+ * - **Modo 0600 ANTES de tener contenido**: la foto lleva los mensajes enteros —contenido de
16
+ * ficheros incluido—, igual que `checkpoint.sqlite`.
17
+ * - **Vive en la carpeta de la sesión**, dentro de `.xonecode/`, que no entra en git ni sube.
18
+ * - **Una tool call sin respuesta se SALDA al guardar** (`saldarColgadas`), con una respuesta
19
+ * que dice la verdad: al modelo le llegaría un mensaje con tool calls sin su respuesta detrás, y
20
+ * Gemini y OpenAI contestan 400. El `OpenToolCallCloser` de TrueForge no cubre este caso:
21
+ * se salta a propósito las que crean un hilo (`create_sub_agent`), que es justo la que queda
22
+ * colgada cuando un turno se corta con un hijo esperando aprobación.
23
+ *
24
+ * **Y la foto lleva VERSIÓN, y se lee de forma ESTRICTA** (`interpretarFoto`). Es un fichero que
25
+ * sobrevive a las subidas de XOneCode y de la librería —que es 0.x y no promete nada entre
26
+ * versiones—, así que lo que no se entiende no se carga a medias: un contexto a medio entender
27
+ * es una conversación que el modelo cree recordar y no recuerda. Fail-closed hacia el lado que
28
+ * NO destruye: una foto que no se entiende no tumba la sesión, se abre SIN memoria y se DICE
29
+ * (`textoDeMemoriaDescartada`), y la foto se APARTA con otro nombre (`apartarMemoria`) en vez de
30
+ * borrarse — o el primer guardado del turno siguiente la pisaría.
31
+ */
32
+ import { chmodSync, existsSync, mkdirSync, openSync, closeSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
33
+ import { basename, dirname, join } from "node:path";
34
+ import { VERSION_DE_TRUEFORGE } from "./trueforge.js";
35
+ /** Un id de sesión que se puede usar como nombre de carpeta: segmento llano y nada más. */
36
+ const ID_VALIDO = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
37
+ /** Dónde vive la memoria de la sesión `hilo`, o `undefined` si el id no es un segmento llano. */
38
+ export function rutaDeMemoria(raiz, hilo) {
39
+ if (!ID_VALIDO.test(hilo))
40
+ return undefined;
41
+ return join(raiz, ".xonecode", "sesiones", hilo, "memoria-trueforge.json");
42
+ }
43
+ /** El texto con que se salda una tool call que el turno no llegó a contestar. */
44
+ export const RESPUESTA_A_UNA_COLGADA = "No se completó: el turno se cortó antes (quedó sin aprobar, se canceló o se agotó el tope). " +
45
+ "Si sigue haciendo falta, vuelve a pedirlo.";
46
+ /**
47
+ * El contexto con las tool calls del ÚLTIMO mensaje del asistente que no tienen respuesta,
48
+ * saldadas. Solo el último: una anterior sin respuesta ya habría roto la conversación antes.
49
+ * Puro: no toca el contexto que recibe.
50
+ */
51
+ export function saldarColgadas(context, excepto) {
52
+ const mensajes = context;
53
+ let ultimo = -1;
54
+ for (let i = mensajes.length - 1; i >= 0; i -= 1) {
55
+ const m = mensajes[i];
56
+ if (m?.role === "assistant" && (m.tool_calls?.length ?? 0) > 0) {
57
+ ultimo = i;
58
+ break;
59
+ }
60
+ }
61
+ if (ultimo === -1)
62
+ return [...context];
63
+ const pedidas = new Set((mensajes[ultimo].tool_calls ?? []).map((t) => t.id).filter((id) => typeof id === "string"));
64
+ for (const m of mensajes.slice(ultimo + 1))
65
+ if (m?.role === "tool" && m.tool_call_id !== undefined)
66
+ pedidas.delete(m.tool_call_id);
67
+ // La que espera la respuesta de la persona no está colgada: está esperando, y saldarla la mataría.
68
+ if (excepto !== undefined)
69
+ pedidas.delete(excepto);
70
+ return [...context, ...[...pedidas].map((id) => ({ role: "tool", tool_call_id: id, content: RESPUESTA_A_UNA_COLGADA }))];
71
+ }
72
+ /** La foto lista para guardar o para rehacer el hilo: con las colgadas saldadas. */
73
+ export function fotoSaneada(foto) {
74
+ const pregunta = foto.pregunta_pendiente;
75
+ return { ...foto, context: saldarColgadas(foto.context, pregunta?.id) };
76
+ }
77
+ // ── La versión del FORMATO, y cómo se llega a ella ────────────────────────────────────────────
78
+ /**
79
+ * La versión del formato de la foto en disco. Sube cuando cambia lo que se escribe, y cada subida
80
+ * trae su entrada en `MIGRACIONES`: una foto de antes se MIGRA al leerla, nunca se descarta por
81
+ * vieja. Es NUESTRA, no la de la librería: la de la librería va aparte, en `trueforge`.
82
+ *
83
+ * El formato v1, entero —y nada más, que es lo que hace estricta la lectura—:
84
+ *
85
+ * ```json
86
+ * { "version": 1, "trueforge": "0.2.1", "context": [...],
87
+ * "current_context_usage": {...}, "capability_state": {...} | null,
88
+ * "pregunta_pendiente": { "hilo": "...", "id": "...", "args": {...}, "encargo"?: "..." } }
89
+ * ```
90
+ *
91
+ * Solo `version` y `context` son obligatorios. `trueforge` es la versión de la librería que
92
+ * escribió el `toSnapshot()`: se APUNTA, no se exige —rechazar por ella tiraría todas las
93
+ * conversaciones en cada subida de la librería—, y está para que una migración futura sepa de
94
+ * dónde parte. Falta en una foto MIGRADA desde v0, porque no se inventa lo que no consta; el
95
+ * guardado siguiente la sella.
96
+ */
97
+ export const VERSION_DE_MEMORIA = 1;
98
+ /**
99
+ * De cada versión a la SIGUIENTE: devuelve la foto migrada o el MOTIVO por el que no se puede.
100
+ * Puras, y se encadenan (`interpretarFoto`), así que una foto de hace tres versiones pasa por
101
+ * las tres. Una migración no valida el resultado final: eso lo hace UNA vez `validarV1`.
102
+ */
103
+ export const MIGRACIONES = {
104
+ /**
105
+ * v0 → v1. La v0 es la foto de antes de versionar: `toSnapshot()` del raíz tal cual, más
106
+ * `pregunta_pendiente`. Traía cuatro campos que el constructor del raíz no recibe de vuelta
107
+ * (`thread_id`, `parent`, `agent_info`, `completion`) y aquí se retiran — pero solo con el valor
108
+ * que tiene un RAÍZ: un `parent` o una `completion` puestos serían la foto de un hijo, y
109
+ * retirarlos en silencio sería cargarla a medias.
110
+ */
111
+ 0: (foto) => {
112
+ const { thread_id, parent, agent_info, completion, ...resto } = foto;
113
+ if (thread_id !== undefined && typeof thread_id !== "string")
114
+ return "la foto sin versión trae un `thread_id` que no es texto";
115
+ for (const [campo, valor] of [
116
+ ["parent", parent],
117
+ ["agent_info", agent_info],
118
+ ["completion", completion],
119
+ ]) {
120
+ if (valor !== undefined && valor !== null)
121
+ return `la foto sin versión trae \`${campo}\`: no es la de un hilo raíz`;
122
+ }
123
+ return { ...resto, version: 1 };
124
+ },
125
+ };
126
+ const esObjeto = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
127
+ /** Un nombre de campo que sale del FICHERO, recortado: el motivo viaja a la pantalla. */
128
+ const nombreDeCampo = (k) => (k.length > 40 ? `${k.slice(0, 40)}…` : k);
129
+ const CAMPOS_V1 = new Set(["version", "trueforge", "context", "current_context_usage", "capability_state", "pregunta_pendiente"]);
130
+ /**
131
+ * La foto v1, comprobada campo a campo, o el motivo. **Un campo que no se conoce es un NO**, no
132
+ * un campo que se ignora: la v1 la escribe `guardarMemoria` con una lista cerrada, así que uno de
133
+ * más significa que no la escribió este código. Y **un campo conocido y mal formado se lleva la
134
+ * foto ENTERA**: soltar solo la pregunta pendiente, por ejemplo, dejaría una conversación que
135
+ * espera una respuesta que ya nadie sabe a qué va.
136
+ *
137
+ * **Límite declarado**: de cada mensaje del contexto se mira que sea un objeto con `role` o `type`
138
+ * de texto, y no más. Su esquema entero es de la librería (zod, dentro de ella), y repetirlo aquí
139
+ * sería un segundo sitio donde decidir qué es un mensaje.
140
+ */
141
+ function validarV1(foto) {
142
+ for (const k of Object.keys(foto))
143
+ if (!CAMPOS_V1.has(k))
144
+ return `campo desconocido «${nombreDeCampo(k)}»`;
145
+ if (foto.version !== 1)
146
+ return "la migración no dejó la versión 1";
147
+ if (foto.trueforge !== undefined && typeof foto.trueforge !== "string")
148
+ return "`trueforge` no es texto";
149
+ const { context, current_context_usage, capability_state, pregunta_pendiente } = foto;
150
+ if (!Array.isArray(context))
151
+ return "falta el contexto, o no es una lista";
152
+ const roto = context.findIndex((m) => !esObjeto(m) || (typeof m.role !== "string" && typeof m.type !== "string"));
153
+ if (roto !== -1)
154
+ return `el mensaje ${roto} del contexto no tiene forma de mensaje`;
155
+ if (current_context_usage !== undefined && !esObjeto(current_context_usage))
156
+ return "`current_context_usage` no es un objeto";
157
+ if (capability_state !== undefined && capability_state !== null && !esObjeto(capability_state))
158
+ return "`capability_state` no es un objeto";
159
+ let pregunta;
160
+ if (pregunta_pendiente !== undefined) {
161
+ const p = pregunta_pendiente;
162
+ if (!esObjeto(p) ||
163
+ typeof p.hilo !== "string" ||
164
+ typeof p.id !== "string" ||
165
+ !esObjeto(p.args) ||
166
+ (p.encargo !== undefined && typeof p.encargo !== "string") ||
167
+ Object.keys(p).some((k) => k !== "hilo" && k !== "id" && k !== "args" && k !== "encargo")) {
168
+ return "la pregunta pendiente está mal formada";
169
+ }
170
+ pregunta = { hilo: p.hilo, id: p.id, args: p.args, ...(typeof p.encargo === "string" ? { encargo: p.encargo } : {}) };
171
+ }
172
+ return {
173
+ context,
174
+ ...(current_context_usage === undefined ? {} : { current_context_usage }),
175
+ ...(capability_state === undefined ? {} : { capability_state: capability_state }),
176
+ ...(pregunta === undefined ? {} : { pregunta_pendiente: pregunta }),
177
+ };
178
+ }
179
+ /**
180
+ * El TEXTO de una foto, entendido: migrado hasta la versión actual y validado, o el motivo por el
181
+ * que no. Pura, y es toda la regla de la lectura. El motivo nunca repite el contenido —un error de
182
+ * `JSON.parse` cita un trozo del fichero, que lleva mensajes enteros— ni ninguna ruta.
183
+ */
184
+ export function interpretarFoto(texto) {
185
+ let crudo;
186
+ try {
187
+ crudo = JSON.parse(texto);
188
+ }
189
+ catch {
190
+ return { estado: "incompatible", motivo: "no es JSON válido" };
191
+ }
192
+ if (!esObjeto(crudo))
193
+ return { estado: "incompatible", motivo: "no es un objeto JSON" };
194
+ // Ausente es v0; `null` NO: no lo escribe nadie, y leerlo como v0 sería adivinar.
195
+ const v = crudo.version === undefined ? 0 : crudo.version;
196
+ if (typeof v !== "number" || !Number.isInteger(v) || v < 0)
197
+ return { estado: "incompatible", motivo: "la versión no es un entero" };
198
+ if (v > VERSION_DE_MEMORIA) {
199
+ return { estado: "incompatible", motivo: `la escribió un XOneCode más nuevo (versión ${v}; este lee hasta la ${VERSION_DE_MEMORIA})` };
200
+ }
201
+ let foto = crudo;
202
+ for (let desde = v; desde < VERSION_DE_MEMORIA; desde += 1) {
203
+ const migrar = MIGRACIONES[desde];
204
+ if (migrar === undefined)
205
+ return { estado: "incompatible", motivo: `no hay migración desde la versión ${desde}` };
206
+ const r = migrar(foto);
207
+ if (typeof r === "string")
208
+ return { estado: "incompatible", motivo: r };
209
+ foto = r;
210
+ }
211
+ const validada = validarV1(foto);
212
+ return typeof validada === "string" ? { estado: "incompatible", motivo: validada } : { estado: "ok", foto: validada };
213
+ }
214
+ /**
215
+ * Escribe la foto, en el formato ACTUAL: la versión y la de la librería las SELLA aquí quien
216
+ * escribe, no quien llama, y los campos van por lista cerrada —lo que `toSnapshot()` traiga de más
217
+ * no llega a disco, y así la lectura estricta no rechaza lo que este mismo código escribió—.
218
+ * El fichero se CREA con 0600 antes de tener contenido y se reemplaza con `renameSync`, para que
219
+ * un corte a mitad no deje media conversación ni un JSON roto.
220
+ */
221
+ export function guardarMemoria(raiz, hilo, foto) {
222
+ const ruta = rutaDeMemoria(raiz, hilo);
223
+ if (ruta === undefined)
224
+ return;
225
+ const saneada = fotoSaneada(foto);
226
+ const pregunta = saneada.pregunta_pendiente;
227
+ const enDisco = {
228
+ version: VERSION_DE_MEMORIA,
229
+ trueforge: VERSION_DE_TRUEFORGE,
230
+ context: saneada.context,
231
+ ...(saneada.current_context_usage === undefined ? {} : { current_context_usage: saneada.current_context_usage }),
232
+ ...(saneada.capability_state === undefined ? {} : { capability_state: saneada.capability_state }),
233
+ ...(pregunta === undefined
234
+ ? {}
235
+ : {
236
+ pregunta_pendiente: {
237
+ hilo: pregunta.hilo,
238
+ id: pregunta.id,
239
+ args: pregunta.args,
240
+ ...(pregunta.encargo === undefined ? {} : { encargo: pregunta.encargo }),
241
+ },
242
+ }),
243
+ };
244
+ mkdirSync(dirname(ruta), { recursive: true });
245
+ const temporal = `${ruta}.${process.pid}.tmp`;
246
+ closeSync(openSync(temporal, "w", 0o600));
247
+ chmodSync(temporal, 0o600);
248
+ writeFileSync(temporal, JSON.stringify(enDisco), { mode: 0o600 });
249
+ renameSync(temporal, ruta);
250
+ }
251
+ /**
252
+ * La memoria de la sesión, con su estado. No tener fichero es `sin-memoria`, no un fallo; uno que
253
+ * existe y no se puede leer es `incompatible` con el `code` de Node y nada más (su mensaje lleva
254
+ * la ruta absoluta). NO aparta ni borra nada: esto lo llama también quien solo PREGUNTA
255
+ * (`hayMemoria`, la web al reabrir), y preguntar no puede mover ficheros.
256
+ */
257
+ export function cargarMemoria(raiz, hilo) {
258
+ const ruta = rutaDeMemoria(raiz, hilo);
259
+ if (ruta === undefined || !existsSync(ruta))
260
+ return { estado: "sin-memoria" };
261
+ let texto;
262
+ try {
263
+ texto = readFileSync(ruta, "utf8");
264
+ }
265
+ catch (e) {
266
+ const code = e.code;
267
+ return { estado: "incompatible", motivo: `no se pudo leer${typeof code === "string" ? ` (${code})` : ""}` };
268
+ }
269
+ return interpretarFoto(texto);
270
+ }
271
+ /** La foto guardada y entendida, o `undefined` si no hay o no se entiende (ver `cargarMemoria`). */
272
+ export function leerMemoria(raiz, hilo) {
273
+ const lectura = cargarMemoria(raiz, hilo);
274
+ return lectura.estado === "ok" ? lectura.foto : undefined;
275
+ }
276
+ /**
277
+ * ¿Hay una conversación de TrueForge que continuar en esta sesión? Solo si la foto se ENTIENDE:
278
+ * una incompatible no se va a cargar, y decir que sí haría que la web presentara como continuada
279
+ * una sesión que empieza de cero.
280
+ */
281
+ export function hayMemoria(raiz, hilo) {
282
+ return cargarMemoria(raiz, hilo).estado === "ok";
283
+ }
284
+ /** Cómo se llama una foto apartada: la de siempre, con la marca y la hora. */
285
+ const APARTADA = /^memoria-trueforge\.incompatible-\d+(?:-\d+)?\.json$/;
286
+ /**
287
+ * Aparta la foto que no se entiende, con otro nombre y en la MISMA carpeta, y devuelve ese nombre
288
+ * (solo el nombre: viaja a la pantalla). Apartar y no borrar, porque no la entendemos y puede que
289
+ * un XOneCode más nuevo sí; y apartar y no dejarla, porque el guardado del primer turno la pisaría.
290
+ * Un nombre que ya existe nunca se pisa. Si no se puede, devuelve `undefined` y quien llama lo
291
+ * DICE: la foto se queda donde estaba y el siguiente guardado la sustituirá.
292
+ */
293
+ export function apartarMemoria(raiz, hilo, ahora = Date.now()) {
294
+ const ruta = rutaDeMemoria(raiz, hilo);
295
+ if (ruta === undefined || !existsSync(ruta))
296
+ return undefined;
297
+ try {
298
+ let nombre = `memoria-trueforge.incompatible-${ahora}.json`;
299
+ for (let n = 1; existsSync(join(dirname(ruta), nombre)); n += 1)
300
+ nombre = `memoria-trueforge.incompatible-${ahora}-${n}.json`;
301
+ renameSync(ruta, join(dirname(ruta), nombre));
302
+ return basename(nombre);
303
+ }
304
+ catch {
305
+ return undefined;
306
+ }
307
+ }
308
+ /**
309
+ * El aviso de una memoria que no se cargó, con el motivo y con lo que se hizo con la foto. Se
310
+ * emite UNA vez, en el primer turno: es cuando importa, porque es el turno en que el modelo no
311
+ * recuerda lo que la pantalla enseña. Solo con una foto que EXISTÍA: sin foto no ha pasado nada.
312
+ */
313
+ export function textoDeMemoriaDescartada(motivo, apartada) {
314
+ return (`⚠ la memoria guardada de esta sesión no se pudo cargar (${motivo}): este turno empieza sin la conversación anterior. ` +
315
+ (apartada === undefined
316
+ ? "No se pudo apartar la foto, y el próximo guardado la sustituirá."
317
+ : `La foto no se ha borrado: queda apartada como «${apartada}» en la carpeta de la sesión.`));
318
+ }
319
+ /** Borra la memoria de la sesión, las fotos apartadas incluidas: lo llama el borrado de una sesión. */
320
+ export function olvidarMemoria(raiz, hilo) {
321
+ const ruta = rutaDeMemoria(raiz, hilo);
322
+ if (ruta === undefined)
323
+ return;
324
+ rmSync(ruta, { force: true });
325
+ let nombres = [];
326
+ try {
327
+ nombres = readdirSync(dirname(ruta));
328
+ }
329
+ catch {
330
+ return;
331
+ }
332
+ for (const n of nombres)
333
+ if (APARTADA.test(n))
334
+ rmSync(join(dirname(ruta), n), { force: true });
335
+ }
336
+ //# sourceMappingURL=memoriaTrueforge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoriaTrueforge.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/memoriaTrueforge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Las métricas PROPIAS de TrueForge (`AgentThreadOrchestrator.getMetrics()`), puestas al lado de
3
+ * las nuestras como CONTRASTE, no como sustituto.
4
+ *
5
+ * Las nuestras salen de traducir cada evento (`eventosTrueforge.ts#traducirEvento`) y son las que
6
+ * se enseñan y se guardan, porque son las mismas cuentas que las de deepagents. Las de la librería
7
+ * las lleva ella por dentro. Si las dos divergen, una de las dos cuenta mal, y hasta ahora no había
8
+ * forma de enterarse: esto lo apunta en la traza (`XONECODE_TRACE_TOOLS=1`) y `xonecode traza` lo
9
+ * dice. Puro, para poder probar la regla sin montar un turno.
10
+ *
11
+ * Se lee al final de CADA turno y es de ESE turno: el raíz se rehace desde su foto al acabar
12
+ * (`sesionTrueforge.ts`), así que el árbol que se mide es el de un solo turno.
13
+ */
14
+ /** De la forma de la librería (`AgentThreadMetrics`) a la nuestra; lo que no es número no consta. */
15
+ export function metricasDeTrueforge(m) {
16
+ const n = (v) => (typeof v === "number" && Number.isFinite(v) ? v : 0);
17
+ const opcional = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
18
+ const cache = opcional(m["total_cache_read_tokens"]);
19
+ const coste = opcional(m["total_cost_in_usd"]);
20
+ return {
21
+ entrada: n(m["total_input_tokens"]),
22
+ salida: n(m["total_output_tokens"]),
23
+ ...(cache === undefined ? {} : { cache }),
24
+ iteraciones: n(m["iterations"]),
25
+ tools: n(m["total_tool_calls"]),
26
+ subagentes: n(m["total_sub_agents"]),
27
+ resumenes: n(m["total_summarizations"]),
28
+ ...(coste === undefined ? {} : { costeUsd: coste }),
29
+ };
30
+ }
31
+ /**
32
+ * En qué difieren, dicho con las dos cifras. Vacío = coinciden.
33
+ *
34
+ * Los TOKENS se comparan tal cual: los dos lados suman el mismo `usage` de cada llamada, así que
35
+ * cualquier diferencia es una cuenta que se pierde en uno de ellos. Las LLAMADAS no se cuentan
36
+ * igual, y las dos diferencias están MEDIDAS contra la librería real: un hijo EXTERNO es una
37
+ * iteración para ella y cero llamadas para nosotros —su gasto es del producto, en la cuenta
38
+ * `externo`—; y una COMPACTACIÓN es una llamada para nosotros —se paga— y para ella no es una
39
+ * iteración, la lleva aparte en `resumenes`. Las dos se ajustan antes de comparar. Y la caché solo
40
+ * si la librería la trae: ausente no es cero.
41
+ */
42
+ export function diferenciasDelContraste(nuestras, suyas, hijosExternos) {
43
+ const salida = [];
44
+ const comparar = (que, nuestra, suya) => {
45
+ if (nuestra !== suya)
46
+ salida.push(`${que}: nuestra ${nuestra}, TrueForge ${suya}`);
47
+ };
48
+ comparar("entrada", nuestras.entrada, suyas.entrada);
49
+ comparar("salida", nuestras.salida, suyas.salida);
50
+ if (suyas.cache !== undefined)
51
+ comparar("caché", nuestras.cache, suyas.cache);
52
+ comparar("llamadas", nuestras.llamadas, suyas.iteraciones - hijosExternos + suyas.resumenes);
53
+ return salida;
54
+ }
55
+ //# sourceMappingURL=metricasTrueforge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metricasTrueforge.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/metricasTrueforge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsBH,qGAAqG;AACrG,MAAM,UAAU,mBAAmB,CAAC,CAA0B;IAC5D,MAAM,CAAC,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnH,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC/C,OAAO;QACL,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;QACnC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACzC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QAC/B,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC/B,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACpC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;QACvC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAwB,EAAE,KAA0B,EAAE,aAAqB;IACjH,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,OAAe,EAAE,IAAY,EAAQ,EAAE;QACpE,IAAI,OAAO,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,aAAa,OAAO,eAAe,IAAI,EAAE,CAAC,CAAC;IACrF,CAAC,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9E,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,GAAG,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * El «modelo» de un hijo EXTERNO de TrueForge: Claude Code, Codex u OpenCode detrás de un
3
+ * `AgentThread` normal.
4
+ *
5
+ * TrueForge exige que su factoría de hijos devuelva un `AgentThread`, y un hilo necesita un
6
+ * `ILLM`; el `Runnable` que deepagents acepta como `CompiledSubAgent` no tiene sitio aquí. Así que
7
+ * el hilo se construye como cualquier otro y lo que cambia es lo que hay detrás de su modelo: una
8
+ * llamada a `SubagenteExternoPort.correr()` —la MISMA integración de deepagents, con sus guardas de
9
+ * ruta, su política de aprobación y su consumo—, cuya respuesta final vuelve como la respuesta del
10
+ * hilo. El bucle agéntico vive dentro del producto, no aquí: el hilo hace UNA llamada y termina.
11
+ *
12
+ * No es un segundo `ILLM`: es un objeto con la forma de un modelo de LangChain —`stream()`— que
13
+ * `modeloParaTrueforge` ya sabe traducir. Un adaptador propio sería un segundo sitio donde
14
+ * componer los trozos que TrueForge espera.
15
+ *
16
+ * **Lo que manda TrueForge al «modelo» se IGNORA** —su identidad, su prompt de sistema, el primer
17
+ * mensaje—: el hijo externo recibe SUS instrucciones y SU encargo, que se capturan al crear el hilo.
18
+ */
19
+ import { AIMessageChunk } from "@langchain/core/messages";
20
+ import { modeloParaTrueforge } from "./modeloLangchain.js";
21
+ import { textoDeFalloExterno } from "../../subagentes/subagenteExterno.js";
22
+ export function modeloExternoParaTrueforge(opciones) {
23
+ return modeloParaTrueforge({
24
+ nombre: "externo",
25
+ modelo: () => ({
26
+ stream: async () => {
27
+ const peticion = opciones.peticion();
28
+ const senal = opciones.senal?.();
29
+ let texto;
30
+ try {
31
+ texto = await opciones.puerto.correr({ ...peticion, ...(senal === undefined ? {} : { senal }) });
32
+ }
33
+ catch (error) {
34
+ // Cancelado: no hay respuesta que dar, y el turno ya se está cerrando por su lado.
35
+ if (senal?.aborted === true)
36
+ throw error;
37
+ texto = textoDeFalloExterno(peticion.motor, error);
38
+ }
39
+ return (async function* () {
40
+ yield new AIMessageChunk({ content: texto });
41
+ })();
42
+ },
43
+ }),
44
+ });
45
+ }
46
+ //# sourceMappingURL=modeloExterno.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modeloExterno.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/modeloExterno.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE3E,MAAM,UAAU,0BAA0B,CAAC,QAM1C;IACC,OAAO,mBAAmB,CAAC;QACzB,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,IAAI,EAAE;gBACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;gBACjC,IAAI,KAAa,CAAC;gBAClB,IAAI,CAAC;oBACH,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBACnG,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,mFAAmF;oBACnF,IAAI,KAAK,EAAE,OAAO,KAAK,IAAI;wBAAE,MAAM,KAAK,CAAC;oBACzC,KAAK,GAAG,mBAAmB,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACrD,CAAC;gBACD,OAAO,CAAC,KAAK,SAAS,CAAC;oBACrB,MAAM,IAAI,cAAc,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC/C,CAAC,CAAC,EAAE,CAAC;YACP,CAAC;SACF,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * El modelo de TrueForge (`ILLM`) hecho con NUESTRO modelo de LangChain.
3
+ *
4
+ * TrueForge trae su propio cliente (`VercelAILLM`), que construye el modelo desde una
5
+ * configuración de proveedor. No se usa, y es la decisión que hace el motor intercambiable sin
6
+ * que se note: nuestros modelos salen de `Modelos.paraPapel()` ya con todo lo que se les ha ido
7
+ * poniendo —el `user_id` de DeepSeek, el eco de su razonamiento, el tope de salida y el
8
+ * pensamiento adaptativo de Claude, el esfuerzo por modelo—, y reconstruirlos con la
9
+ * configuración de TrueForge lo perdería todo en silencio.
10
+ *
11
+ * El contrato de TrueForge habla en la forma de las chat completions de OpenAI, así que esto es
12
+ * una traducción en los dos sentidos: los mensajes que manda a mensajes de LangChain, y el stream
13
+ * de LangChain a los fragmentos que espera.
14
+ *
15
+ * **La cancelación entra por aquí**: `ILLM.create` no recibe señal, así que la de la llamada en
16
+ * curso se pide a `senal()` en cada `create`, y quien corre el turno la pone.
17
+ */
18
+ import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
19
+ import { razonamientoDe, razonamientoVisibleDe, textoDe } from "../../turno/puente.js";
20
+ /** El texto de un `content` de OpenAI, sea cadena o lista de partes. */
21
+ function textoDeContenido(contenido) {
22
+ if (typeof contenido === "string")
23
+ return contenido;
24
+ if (!Array.isArray(contenido))
25
+ return "";
26
+ return contenido
27
+ .map((p) => (typeof p === "object" && p !== null && p.type === "text" ? String(p.text) : ""))
28
+ .join("");
29
+ }
30
+ /** Los argumentos de una tool call, que en OpenAI viajan como cadena JSON. Rotos = `{}`. */
31
+ function argumentosDe(json) {
32
+ try {
33
+ const v = JSON.parse(json);
34
+ return typeof v === "object" && v !== null ? v : {};
35
+ }
36
+ catch {
37
+ return {};
38
+ }
39
+ }
40
+ /** Los mensajes que manda TrueForge, en mensajes de LangChain. */
41
+ export function aMensajesDeLangchain(mensajes) {
42
+ return mensajes.map((m) => {
43
+ switch (m.role) {
44
+ case "system":
45
+ case "developer":
46
+ return new SystemMessage(textoDeContenido(m.content));
47
+ case "assistant":
48
+ return new AIMessage({
49
+ content: textoDeContenido(m.content),
50
+ tool_calls: (m.tool_calls ?? []).map((t) => ({ id: t.id, name: t.function.name, args: argumentosDe(t.function.arguments), type: "tool_call" })),
51
+ // El razonamiento de la vuelta anterior, por si el proveedor lo exige de vuelta
52
+ // (DeepSeek): el eco lo repone por id de tool call, pero no se tira si viene.
53
+ ...(m.reasoning_content === undefined ? {} : { additional_kwargs: { reasoning_content: m.reasoning_content } }),
54
+ });
55
+ case "tool":
56
+ return new ToolMessage({ tool_call_id: m.tool_call_id ?? "", content: textoDeContenido(m.content) });
57
+ default:
58
+ // `user` y cualquier otro rol: el contenido tal cual, que puede traer imágenes.
59
+ return new HumanMessage({ content: (typeof m.content === "string" || Array.isArray(m.content) ? m.content : "") });
60
+ }
61
+ });
62
+ }
63
+ /**
64
+ * Un `ILLM` sobre un modelo de LangChain. `modelo` y `senal` son funciones y no valores: el modelo
65
+ * cambia con `/modelo` sin rehacer el hilo, y la señal es la de la llamada EN CURSO.
66
+ */
67
+ export function modeloParaTrueforge(opciones) {
68
+ let secuencia = 0;
69
+ async function* crear(cuerpo) {
70
+ const base = opciones.modelo();
71
+ const tools = cuerpo.tools ?? [];
72
+ const modelo = tools.length > 0 && typeof base.bindTools === "function" ? base.bindTools(tools) : base;
73
+ const mensajes = aMensajesDeLangchain(cuerpo.messages);
74
+ const senal = opciones.senal?.();
75
+ const id = `xc-${++secuencia}`;
76
+ const creado = Math.floor(Date.now() / 1000);
77
+ const nombre = opciones.nombre ?? "xonecode";
78
+ let acumulado;
79
+ for await (const trozo of await modelo.stream(mensajes, senal === undefined ? {} : { signal: senal })) {
80
+ acumulado = acumulado === undefined ? trozo : acumulado.concat(trozo);
81
+ const texto = textoDe(trozo);
82
+ // En los TROZOS va el razonamiento que se ENSEÑA, DeepSeek incluido: los trozos solo
83
+ // alimentan los eventos del chat. El mensaje que se guarda en el hilo es el `output` de
84
+ // abajo, que sigue con `razonamientoDe` — lo de DeepSeek no entra en la memoria.
85
+ const pensado = razonamientoVisibleDe(trozo);
86
+ const llamadas = (trozo.tool_call_chunks ?? []).map((t, i) => ({
87
+ index: t.index ?? i,
88
+ ...(t.id === undefined ? {} : { id: t.id, type: "function" }),
89
+ function: { ...(t.name === undefined ? {} : { name: t.name }), arguments: t.args ?? "" },
90
+ }));
91
+ if (texto === "" && pensado === "" && llamadas.length === 0)
92
+ continue;
93
+ yield {
94
+ id,
95
+ object: "chat.completion.chunk",
96
+ created: creado,
97
+ model: nombre,
98
+ choices: [
99
+ {
100
+ index: 0,
101
+ delta: {
102
+ role: "assistant",
103
+ ...(texto === "" ? {} : { content: texto }),
104
+ ...(pensado === "" ? {} : { reasoning_content: pensado }),
105
+ ...(llamadas.length === 0 ? {} : { tool_calls: llamadas }),
106
+ },
107
+ finish_reason: null,
108
+ },
109
+ ],
110
+ };
111
+ }
112
+ const llamadas = acumulado?.tool_calls ?? [];
113
+ const uso = acumulado?.usage_metadata;
114
+ const razonamiento = acumulado === undefined ? "" : razonamientoDe(acumulado);
115
+ return {
116
+ output: {
117
+ role: "assistant",
118
+ content: acumulado === undefined ? "" : textoDe(acumulado),
119
+ ...(llamadas.length === 0
120
+ ? {}
121
+ : {
122
+ tool_calls: llamadas.map((t, i) => ({
123
+ id: t.id ?? `${id}-${i}`,
124
+ type: "function",
125
+ function: { name: t.name, arguments: JSON.stringify(t.args ?? {}) },
126
+ })),
127
+ }),
128
+ ...(razonamiento === "" ? {} : { reasoning_content: razonamiento }),
129
+ },
130
+ usage: {
131
+ input_tokens: uso?.input_tokens ?? 0,
132
+ output_tokens: uso?.output_tokens ?? 0,
133
+ total_tokens: uso?.total_tokens ?? 0,
134
+ ...(uso?.input_token_details?.cache_read === undefined ? {} : { cache_read_tokens: uso.input_token_details.cache_read }),
135
+ },
136
+ finish_reason: llamadas.length > 0 ? "tool_calls" : "stop",
137
+ };
138
+ }
139
+ return {
140
+ create: (cuerpo) => crear(cuerpo),
141
+ // La compactación de contexto de TrueForge pide una respuesta entera: el mismo camino,
142
+ // agotado.
143
+ createNonStream: async (cuerpo) => {
144
+ const it = crear(cuerpo);
145
+ let r = await it.next();
146
+ while (!r.done)
147
+ r = await it.next();
148
+ return r.value;
149
+ },
150
+ };
151
+ }
152
+ //# sourceMappingURL=modeloLangchain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modeloLangchain.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/modeloLangchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,SAAS,EAAkB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAoB,MAAM,0BAA0B,CAAC;AAEjI,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAgBvF,wEAAwE;AACxE,SAAS,gBAAgB,CAAC,SAAkB;IAC1C,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,OAAO,SAAS;SACb,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAAuB,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAE,CAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC1I,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,4FAA4F;AAC5F,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,CAAC,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAE,CAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,oBAAoB,CAAC,QAAkC;IACrE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAe,EAAE;QACrC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,QAAQ,CAAC;YACd,KAAK,WAAW;gBACd,OAAO,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACxD,KAAK,WAAW;gBACd,OAAO,IAAI,SAAS,CAAC;oBACnB,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;oBACpC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAoB,EAAE,CAAC,CAAC;oBACxJ,gFAAgF;oBAChF,8EAA8E;oBAC9E,GAAG,CAAC,CAAC,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,EAAE,CAAC;iBAChH,CAAC,CAAC;YACL,KAAK,MAAM;gBACT,OAAO,IAAI,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACvG;gBACE,gFAAgF;gBAChF,OAAO,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAU,EAAE,CAAC,CAAC;QAChI,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAInC;IACC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,SAAS,CAAC,CAAC,KAAK,CAAC,MAAkD;QAKtE,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAuB,CAAC;QACpD,MAAM,KAAK,GAAI,MAAgC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvG,MAAM,QAAQ,GAAG,oBAAoB,CAAE,MAAwC,CAAC,QAAQ,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,UAAU,CAAC;QAE7C,IAAI,SAAqC,CAAC;QAC1C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YACtG,SAAS,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7B,qFAAqF;YACrF,wFAAwF;YACxF,iFAAiF;YACjF,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7D,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;gBACnB,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAmB,EAAE,CAAC;gBACtE,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE;aACzF,CAAC,CAAC,CAAC;YACJ,IAAI,KAAK,KAAK,EAAE,IAAI,OAAO,KAAK,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACtE,MAAM;gBACJ,EAAE;gBACF,MAAM,EAAE,uBAAuB;gBAC/B,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE;oBACP;wBACE,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE;4BACL,IAAI,EAAE,WAAW;4BACjB,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;4BAC3C,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;4BACzD,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;yBAC3D;wBACD,aAAa,EAAE,IAAI;qBACpB;iBACF;aAC6B,CAAC;QACnC,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,EAAE,UAAU,IAAI,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,SAAS,EAAE,cAAc,CAAC;QACtC,MAAM,YAAY,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC9E,OAAO;YACL,MAAM,EAAE;gBACN,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;gBAC1D,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;oBACvB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;4BAClC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE;4BACxB,IAAI,EAAE,UAAmB;4BACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE;yBACpE,CAAC,CAAC;qBACJ,CAAC;gBACN,GAAG,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC;aACpE;YACD,KAAK,EAAE;gBACL,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,CAAC;gBACpC,aAAa,EAAE,GAAG,EAAE,aAAa,IAAI,CAAC;gBACtC,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,CAAC;gBACpC,GAAG,CAAC,GAAG,EAAE,mBAAmB,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC;aACzH;YACD,aAAa,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM;SAC3B,CAAC;IACpC,CAAC;IAED,OAAO;QACL,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;QACjC,uFAAuF;QACvF,WAAW;QACX,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,CAAC,CAAC,IAAI;gBAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}