xonecode 0.29.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/web/dist/assets/{EditorDeFichero-ChyJtiiz.js → EditorDeFichero-H_kGeZt2.js} +1 -1
- package/apps/web/dist/assets/{index-IptObD2z.css → index-CWBaotdZ.css} +1 -1
- package/apps/web/dist/assets/index-DnGuOvbb.js +499 -0
- package/apps/web/dist/assets/{php-B91ZcS-9.js → php-CMFQiZgk.js} +1 -1
- package/apps/web/dist/assets/{ruby-DrxrTSz0.js → ruby-Dj3BOBHc.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/config/modelosDeMotor.js +4 -2
- package/dist/agent/config/modelosDeMotor.js.map +1 -1
- package/dist/agent/config/settingsEnDisco.js +26 -0
- package/dist/agent/config/settingsEnDisco.js.map +1 -1
- package/dist/agent/dispositivos/cajasDeMaqueta.js +130 -0
- package/dist/agent/dispositivos/cajasDeMaqueta.js.map +1 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js +25 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js.map +1 -0
- package/dist/agent/dispositivos/juezVisual.js +84 -3
- package/dist/agent/dispositivos/juezVisual.js.map +1 -1
- package/dist/agent/grafo/criticaVisual.js +240 -11
- package/dist/agent/grafo/criticaVisual.js.map +1 -1
- package/dist/agent/grafo/lectorDeReferencias.js +21 -0
- package/dist/agent/grafo/lectorDeReferencias.js.map +1 -1
- package/dist/agent/grafo/validarFicheroXone.js +114 -0
- package/dist/agent/grafo/validarFicheroXone.js.map +1 -0
- package/dist/agent/motores/motoresLocales.js +429 -0
- package/dist/agent/motores/motoresLocales.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +79 -11
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
- package/dist/agent/motores/trueforge/toolsDeFichero.js +24 -6
- package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -1
- package/dist/agent/sesiones/adjuntosDeSesion.js +125 -5
- package/dist/agent/sesiones/adjuntosDeSesion.js.map +1 -1
- package/dist/agent/subagentes/ejecutableEnWindows.js +139 -0
- package/dist/agent/subagentes/ejecutableEnWindows.js.map +1 -0
- package/dist/agent/subagentes/subagenteCodex.js +7 -2
- package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
- package/dist/agent/subagentes/subagenteOpencode.js +12 -5
- package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
- package/dist/agent/turno/resumenDeTool.js +2 -0
- package/dist/agent/turno/resumenDeTool.js.map +1 -1
- package/dist/core/adjuntos.js +10 -2
- package/dist/core/adjuntos.js.map +1 -1
- package/dist/core/contextos.js +20 -0
- package/dist/core/contextos.js.map +1 -1
- package/dist/core/cssBienFormado.js +97 -0
- package/dist/core/cssBienFormado.js.map +1 -0
- package/dist/core/descripcionDePantalla.js +354 -0
- package/dist/core/descripcionDePantalla.js.map +1 -0
- package/dist/core/estiloMedido.js +332 -0
- package/dist/core/estiloMedido.js.map +1 -0
- package/dist/core/geometriaDePantalla.js +437 -0
- package/dist/core/geometriaDePantalla.js.map +1 -0
- package/dist/core/jsParaRhino.js +93 -0
- package/dist/core/jsParaRhino.js.map +1 -0
- package/dist/core/motoresLocales.js +128 -0
- package/dist/core/motoresLocales.js.map +1 -0
- package/dist/core/notify.js +2 -0
- package/dist/core/notify.js.map +1 -1
- package/dist/core/nucleoXone.js +6 -6
- package/dist/core/nucleoXone.js.map +1 -1
- package/dist/core/settings.js +5 -0
- package/dist/core/settings.js.map +1 -1
- package/dist/core/shellDeAgente.js +13 -0
- package/dist/core/shellDeAgente.js.map +1 -1
- package/dist/core/xmlBienFormado.js +206 -0
- package/dist/core/xmlBienFormado.js.map +1 -0
- package/dist/core/zipDeAdjunto.js +79 -0
- package/dist/core/zipDeAdjunto.js.map +1 -0
- package/dist/web/servidor/arranque.js +84 -0
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/package.json +2 -1
- package/skills/xone-development/SKILL.md +2 -1
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +2 -1
- package/skills/xone-development/references/css/de-una-maqueta-a-xone.md +81 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +15 -13
- package/skills/xone-development/references/css/propiedades-y-herencia.md +2 -2
- package/skills/xone-development/references/css/selectores-unidades-colores.md +8 -3
- package/skills/xone-development/references/indice-completo.md +1 -0
- package/skills/xone-hotswap/lib/geometria.mjs +147 -0
- package/skills/xone-hotswap/scripts/xone-captura-android +6 -0
- package/skills/xone-hotswap/scripts/xone-hotswap +8 -0
- package/skills/xone-hotswap/scripts/xone-recargar-android +15 -0
- package/apps/web/dist/assets/index-CFIrUOmW.js +0 -499
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Los motores locales en la máquina: medir si están y con qué sesión, PROBARLOS con un encargo de
|
|
3
|
+
* verdad, e iniciar la sesión de Claude Code desde un botón. Las reglas puras están en
|
|
4
|
+
* `core/motoresLocales.ts`; aquí solo hay procesos.
|
|
5
|
+
*
|
|
6
|
+
* Tres decisiones que no se ven en el código:
|
|
7
|
+
*
|
|
8
|
+
* - **Se mide el binario que el SDK LANZA**, el de su paquete de plataforma, y no el `claude` del
|
|
9
|
+
* PATH: pueden ser versiones distintas (medido: 2.1.263 frente a 2.1.287), y medir el otro
|
|
10
|
+
* diría algo de un programa que los subagentes no corren. Sin respaldo al PATH, a propósito.
|
|
11
|
+
* - **La prueba sale por el MISMO puerto que un encargo real** (`crearSubagenteExterno().correr`),
|
|
12
|
+
* no por un `query()` montado aquí: una prueba con sus propias opciones mediría otra cosa —el
|
|
13
|
+
* patrón de fallo de siempre, una composición que solo existe donde nadie la usa—.
|
|
14
|
+
* - **`auth login` funciona sin TTY** (medido con el binario del SDK y un `CLAUDE_CONFIG_DIR`
|
|
15
|
+
* aislado): abre el navegador él solo, imprime un enlace de respaldo y espera «Paste code here
|
|
16
|
+
* if prompted». Así que el botón lanza el proceso y, si la web enseña un código, se le pasa
|
|
17
|
+
* por `stdin`. **El enlace no cruza el cable** (la regla de los conectores): si el navegador
|
|
18
|
+
* no se abrió, lo vuelve a abrir el SERVIDOR. Límite declarado: por un túnel no sirve.
|
|
19
|
+
*/
|
|
20
|
+
import { exec, execFile, spawn } from "node:child_process";
|
|
21
|
+
import { mkdirSync } from "node:fs";
|
|
22
|
+
import { createRequire } from "node:module";
|
|
23
|
+
import { tmpdir } from "node:os";
|
|
24
|
+
import { join } from "node:path";
|
|
25
|
+
import { promisify } from "node:util";
|
|
26
|
+
import { INSTRUCCIONES_DE_PRUEBA, MOTORES_CON_MODELO, MOTORES_LOCALES, motivoDeModeloDeMotorInaceptable, TAREA_DE_PRUEBA, interpretarAuthStatusDeClaude, lineaDeSesionDeClaude, pideCodigo, recortar, respuestaDePruebaValida, sinUrls, ultimaLinea, urlDeAutorizacion, versionDeSalida, } from "../../core/motoresLocales.js";
|
|
27
|
+
import { entornoDeShell } from "../../core/shellDeAgente.js";
|
|
28
|
+
import { mensajeSeguro } from "../../core/trazaDeErrores.js";
|
|
29
|
+
import { describirFallo } from "../dispositivos/dispositivosEnMaquina.js";
|
|
30
|
+
import { abrirEnSistema } from "../cloudstudio/cloudstudioMcp.js";
|
|
31
|
+
import { crearSubagenteExterno } from "../subagentes/subagenteExterno.js";
|
|
32
|
+
import { binarioDeCodex } from "../subagentes/subagenteCodex.js";
|
|
33
|
+
import { binarioDeOpencode } from "../subagentes/subagenteOpencode.js";
|
|
34
|
+
import { guardarModeloDeOpencode, modeloDeOpencodeGuardado } from "../config/settingsEnDisco.js";
|
|
35
|
+
/** `--version` y `auth status`: si tardan más, el binario no está bien. */
|
|
36
|
+
export const TOPE_DE_MEDIDA_MS = 15_000;
|
|
37
|
+
/** Un primer arranque de Claude Code en frío tarda; dos minutos es «no contesta». */
|
|
38
|
+
export const TOPE_DE_PRUEBA_MS = 120_000;
|
|
39
|
+
/** Lo que se espera a que la persona termine en el navegador. */
|
|
40
|
+
export const TOPE_DE_LOGIN_MS = 10 * 60_000;
|
|
41
|
+
/**
|
|
42
|
+
* El `claude` del paquete de plataforma del SDK, con la MISMA regla con que lo busca el SDK
|
|
43
|
+
* (`sdk.mjs`): `@anthropic-ai/claude-agent-sdk-<plataforma>-<arquitectura>/claude[.exe]`, y en
|
|
44
|
+
* Linux las dos variantes de libc. Resuelto por el cargador de módulos, nunca contando `..`.
|
|
45
|
+
*/
|
|
46
|
+
export function binarioDeClaudeDelSdk(plataforma = process.platform, arquitectura = process.arch, resolver = createRequire(import.meta.url).resolve) {
|
|
47
|
+
const base = "@anthropic-ai/claude-agent-sdk";
|
|
48
|
+
const paquetes = plataforma === "linux" ? [`${base}-linux-${arquitectura}`, `${base}-linux-${arquitectura}-musl`] : [`${base}-${plataforma}-${arquitectura}`];
|
|
49
|
+
const sufijo = plataforma === "win32" ? ".exe" : "";
|
|
50
|
+
for (const paquete of paquetes) {
|
|
51
|
+
try {
|
|
52
|
+
return resolver(`${paquete}/claude${sufijo}`);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// No está esta variante: la siguiente.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
/** El entorno de NUESTRA shell, sin claves de API: el de un subagente con `ejecucion`. */
|
|
61
|
+
function limpio(entorno) {
|
|
62
|
+
return entornoDeShell({ entorno });
|
|
63
|
+
}
|
|
64
|
+
/** ¿El entorno heredado lleva algo de Anthropic que el limpio quita? Entonces son dos caminos. */
|
|
65
|
+
function heredaClaveDeAnthropic(entorno) {
|
|
66
|
+
const sin = limpio(entorno);
|
|
67
|
+
return Object.keys(entorno).some((k) => k.startsWith("ANTHROPIC_") && entorno[k] !== undefined && !(k in sin));
|
|
68
|
+
}
|
|
69
|
+
const execFileP = promisify(execFile);
|
|
70
|
+
const execP = promisify(exec);
|
|
71
|
+
/**
|
|
72
|
+
* Un proceso corto de verdad. Un nombre a secas en Windows va por la shell: `codex` y `opencode`
|
|
73
|
+
* los instala npm como `.cmd`, y `execFile` sin shell no los encuentra. Los argumentos son
|
|
74
|
+
* constantes de este fichero, así que componer la línea no abre ninguna inyección.
|
|
75
|
+
*/
|
|
76
|
+
async function ejecutarReal(binario, args, opciones) {
|
|
77
|
+
const env = opciones.entorno;
|
|
78
|
+
if (process.platform === "win32" && !/[\\/]/.test(binario)) {
|
|
79
|
+
const { stdout, stderr } = await execP([binario, ...args].join(" "), { timeout: opciones.timeout, env, windowsHide: true, encoding: "utf8" });
|
|
80
|
+
return { stdout: String(stdout), stderr: String(stderr) };
|
|
81
|
+
}
|
|
82
|
+
const { stdout, stderr } = await execFileP(binario, [...args], { timeout: opciones.timeout, env, windowsHide: true, encoding: "utf8" });
|
|
83
|
+
return { stdout: String(stdout), stderr: String(stderr) };
|
|
84
|
+
}
|
|
85
|
+
function lanzarReal(binario, args, opciones) {
|
|
86
|
+
return spawn(binario, [...args], { env: opciones.entorno, stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Una terminal con el comando ya escrito: el respaldo de cuando el botón no puede (el navegador
|
|
90
|
+
* es de otra máquina, o la persona prefiere verlo). Solo Windows y macOS, donde se sabe qué
|
|
91
|
+
* terminal hay; en el resto no se ofrece, que es mejor que un botón que no hace nada.
|
|
92
|
+
*/
|
|
93
|
+
function abrirTerminalReal(binario, args, entorno) {
|
|
94
|
+
const env = entorno;
|
|
95
|
+
if (process.platform === "win32") {
|
|
96
|
+
const comando = `& '${binario.replace(/'/g, "''")}' ${args.join(" ")}`;
|
|
97
|
+
const hijo = spawn("cmd.exe", ["/c", "start", "", "powershell", "-NoExit", "-Command", comando], { env, detached: true, stdio: "ignore" });
|
|
98
|
+
hijo.on("error", () => { });
|
|
99
|
+
hijo.unref();
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (process.platform === "darwin") {
|
|
103
|
+
const linea = `'${binario.replace(/'/g, `'\\''`)}' ${args.join(" ")}`;
|
|
104
|
+
const guion = `tell application "Terminal" to do script "${linea.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
105
|
+
const hijo = spawn("osascript", ["-e", guion, "-e", 'tell application "Terminal" to activate'], { env, detached: true, stdio: "ignore" });
|
|
106
|
+
hijo.on("error", () => { });
|
|
107
|
+
hijo.unref();
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* La prueba de producción: el MISMO puerto que corre un subagente, sin política de escritura
|
|
114
|
+
* (nada que escribir) y en una carpeta vacía fuera de cualquier proyecto. Con `con-ejecucion`
|
|
115
|
+
* lleva el entorno limpio, que es lo que recibe un agente con `ejecucion: true`.
|
|
116
|
+
*/
|
|
117
|
+
async function probarReal(peticion) {
|
|
118
|
+
const cwd = join(tmpdir(), "xonecode-prueba-de-motor");
|
|
119
|
+
mkdirSync(cwd, { recursive: true });
|
|
120
|
+
return crearSubagenteExterno({}).correr({
|
|
121
|
+
motor: peticion.motor,
|
|
122
|
+
cwd,
|
|
123
|
+
instrucciones: INSTRUCCIONES_DE_PRUEBA,
|
|
124
|
+
tarea: TAREA_DE_PRUEBA,
|
|
125
|
+
permitirEscritura: false,
|
|
126
|
+
agente: "prueba-de-conexion",
|
|
127
|
+
senal: peticion.senal,
|
|
128
|
+
...(peticion.camino === "con-ejecucion" ? { ejecucion: { scripts: [], entorno: peticion.entornoLimpio, lecturas: [] } } : {}),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* La salida de un proceso que contesta TAMBIÉN cuando sale con otro código: `claude auth status`
|
|
133
|
+
* sin sesión imprime su JSON y sale con 1 (medido). Un tope o un binario que no está sí lanzan.
|
|
134
|
+
*/
|
|
135
|
+
async function salidaAunqueFalle(promesa) {
|
|
136
|
+
try {
|
|
137
|
+
return (await promesa).stdout;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
const e = error;
|
|
141
|
+
if (e !== null && typeof e === "object" && e.killed !== true && typeof e.code === "number" && typeof e.stdout === "string") {
|
|
142
|
+
return e.stdout;
|
|
143
|
+
}
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Lo que se cuenta de un error: una línea, sin rutas ni enlaces. */
|
|
148
|
+
function motivoDe(error, topeMs) {
|
|
149
|
+
return recortar(sinUrls(mensajeSeguro(describirFallo(error, topeMs))));
|
|
150
|
+
}
|
|
151
|
+
export function crearServicioDeMotoresLocales(deps) {
|
|
152
|
+
const plataforma = deps.plataforma ?? process.platform;
|
|
153
|
+
const entorno = () => deps.entorno ?? process.env;
|
|
154
|
+
const ahora = () => (deps.ahora ?? (() => new Date()))().toISOString();
|
|
155
|
+
const binarioDeClaude = deps.binarioDeClaude ?? (() => binarioDeClaudeDelSdk());
|
|
156
|
+
const ejecutar = deps.ejecutar ?? ejecutarReal;
|
|
157
|
+
const lanzar = deps.lanzar ?? lanzarReal;
|
|
158
|
+
const probarMotor = deps.probar ?? probarReal;
|
|
159
|
+
const abrir = deps.abrir ?? ((url) => abrirEnSistema(new URL(url)));
|
|
160
|
+
const abrirTerminal = deps.abrirTerminal ?? abrirTerminalReal;
|
|
161
|
+
const admiteConsola = deps.abrirTerminal !== undefined || plataforma === "win32" || plataforma === "darwin";
|
|
162
|
+
const leerModelo = deps.leerModelo ?? ((motor) => (motor === "opencode" ? modeloDeOpencodeGuardado() : undefined));
|
|
163
|
+
const guardarModelo = deps.guardarModelo ??
|
|
164
|
+
((motor, modelo) => {
|
|
165
|
+
if (motor === "opencode")
|
|
166
|
+
guardarModeloDeOpencode(undefined, modelo);
|
|
167
|
+
});
|
|
168
|
+
/** Lo que la tarjeta necesita para el selector: que lo admite, y cuál hay. */
|
|
169
|
+
const deModelo = (motor) => {
|
|
170
|
+
if (!MOTORES_CON_MODELO.includes(motor))
|
|
171
|
+
return {};
|
|
172
|
+
const modelo = leerModelo(motor);
|
|
173
|
+
return { admiteModelo: true, ...(modelo === undefined ? {} : { modelo }) };
|
|
174
|
+
};
|
|
175
|
+
const estados = new Map();
|
|
176
|
+
const logins = new Map();
|
|
177
|
+
let medida;
|
|
178
|
+
const poner = (motor, cambio, quitar = []) => {
|
|
179
|
+
const antes = estados.get(motor) ?? { motor, instalado: "fallo", medido: ahora() };
|
|
180
|
+
const nuevo = { ...antes, ...cambio };
|
|
181
|
+
for (const campo of quitar)
|
|
182
|
+
delete nuevo[campo];
|
|
183
|
+
estados.set(motor, nuevo);
|
|
184
|
+
deps.alCambiar();
|
|
185
|
+
};
|
|
186
|
+
async function medirClaude() {
|
|
187
|
+
const bin = binarioDeClaude();
|
|
188
|
+
if (bin === undefined) {
|
|
189
|
+
return { instalado: "no-encontrado", detalle: "el SDK de Claude Code no trae binario para este sistema" };
|
|
190
|
+
}
|
|
191
|
+
let version;
|
|
192
|
+
try {
|
|
193
|
+
version = versionDeSalida((await ejecutar(bin, ["--version"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() })).stdout);
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
return { instalado: "fallo", detalle: motivoDe(error, TOPE_DE_MEDIDA_MS) };
|
|
197
|
+
}
|
|
198
|
+
const base = { instalado: "ok", admiteLogin: true, ...(admiteConsola ? { admiteConsola: true } : {}), ...(version === undefined ? {} : { version }) };
|
|
199
|
+
try {
|
|
200
|
+
const sesion = interpretarAuthStatusDeClaude(await salidaAunqueFalle(ejecutar(bin, ["auth", "status", "--json"], { timeout: TOPE_DE_MEDIDA_MS, entorno: limpio(entorno()) })));
|
|
201
|
+
if (sesion === undefined)
|
|
202
|
+
return { ...base, detalle: "no se pudo leer el estado de la sesión" };
|
|
203
|
+
let conClave = false;
|
|
204
|
+
if (heredaClaveDeAnthropic(entorno())) {
|
|
205
|
+
const heredada = interpretarAuthStatusDeClaude(await salidaAunqueFalle(ejecutar(bin, ["auth", "status", "--json"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() })));
|
|
206
|
+
conClave = heredada?.porClave === true;
|
|
207
|
+
}
|
|
208
|
+
return { ...base, conSesion: sesion.iniciada, sesion: lineaDeSesionDeClaude(sesion), ...(conClave ? { conClave: true } : {}) };
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
return { ...base, detalle: `no se pudo leer la sesión: ${motivoDe(error, TOPE_DE_MEDIDA_MS)}` };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Codex y OpenCode: si están y qué versión. La sesión de Codex se lee de `codex login status`,
|
|
216
|
+
* que sale con 0 solo con sesión (y dice cuál en una línea). La de OpenCode NO se lee: `auth
|
|
217
|
+
* list` pinta una tabla para personas, y adivinar de ella sería afirmar sin medida — lo dice la
|
|
218
|
+
* prueba. Límite declarado: ninguno de los dos estaba instalado donde se escribió esto.
|
|
219
|
+
*/
|
|
220
|
+
async function medirOtro(motor) {
|
|
221
|
+
const bin = motor === "codex" ? binarioDeCodex() : binarioDeOpencode();
|
|
222
|
+
let version;
|
|
223
|
+
try {
|
|
224
|
+
const s = await ejecutar(bin, ["--version"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() });
|
|
225
|
+
version = versionDeSalida(`${s.stdout}\n${s.stderr}`);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
const e = error;
|
|
229
|
+
const noEsta = e?.code === "ENOENT" ||
|
|
230
|
+
e?.code === 127 ||
|
|
231
|
+
(e?.code === 1 && typeof e.stderr === "string" && /not recognized|no se reconoce/i.test(e.stderr));
|
|
232
|
+
return noEsta
|
|
233
|
+
? { instalado: "no-encontrado", detalle: `${motor} no está instalado o no está en el PATH` }
|
|
234
|
+
: { instalado: "fallo", detalle: motivoDe(error, TOPE_DE_MEDIDA_MS) };
|
|
235
|
+
}
|
|
236
|
+
const base = { instalado: "ok", ...(version === undefined ? {} : { version }) };
|
|
237
|
+
if (motor === "opencode")
|
|
238
|
+
return base;
|
|
239
|
+
try {
|
|
240
|
+
const s = await ejecutar(bin, ["login", "status"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() });
|
|
241
|
+
const linea = ultimaLinea(`${s.stdout}\n${s.stderr}`);
|
|
242
|
+
return { ...base, conSesion: true, ...(linea === undefined ? {} : { sesion: linea }) };
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
const e = error;
|
|
246
|
+
if (e?.killed === true)
|
|
247
|
+
return { ...base, detalle: motivoDe(error, TOPE_DE_MEDIDA_MS) };
|
|
248
|
+
const linea = ultimaLinea(`${typeof e?.stdout === "string" ? e.stdout : ""}\n${typeof e?.stderr === "string" ? e.stderr : ""}`);
|
|
249
|
+
return { ...base, conSesion: false, sesion: linea ?? "Sin sesión iniciada" };
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async function medirTodos() {
|
|
253
|
+
const medidas = await Promise.all(MOTORES_LOCALES.map(async (motor) => [motor, motor === "claude-code" ? await medirClaude() : await medirOtro(motor)]));
|
|
254
|
+
const medido = ahora();
|
|
255
|
+
for (const [motor, medidaDelMotor] of medidas) {
|
|
256
|
+
const antes = estados.get(motor);
|
|
257
|
+
// Lo que no es de la medida —las pruebas, el login en curso, «probando»— se conserva:
|
|
258
|
+
// volver a medir no borra la respuesta que se acaba de ver.
|
|
259
|
+
const conserva = {
|
|
260
|
+
...(antes?.pruebas === undefined ? {} : { pruebas: antes.pruebas }),
|
|
261
|
+
...(antes?.probando === undefined ? {} : { probando: antes.probando }),
|
|
262
|
+
...(antes?.login === undefined ? {} : { login: antes.login }),
|
|
263
|
+
};
|
|
264
|
+
estados.set(motor, { motor, ...medidaDelMotor, ...deModelo(motor), ...conserva, medido });
|
|
265
|
+
}
|
|
266
|
+
deps.alCambiar();
|
|
267
|
+
}
|
|
268
|
+
const servicio = {
|
|
269
|
+
foto: () => (estados.size === 0 ? undefined : MOTORES_LOCALES.flatMap((m) => estados.get(m) ?? [])),
|
|
270
|
+
medir() {
|
|
271
|
+
// Dos «Volver a comprobar» seguidos esperan a la MISMA medida en vez de lanzar otra.
|
|
272
|
+
medida ??= medirTodos().finally(() => {
|
|
273
|
+
medida = undefined;
|
|
274
|
+
});
|
|
275
|
+
return medida;
|
|
276
|
+
},
|
|
277
|
+
async probar(motor) {
|
|
278
|
+
if (estados.get(motor)?.probando === true)
|
|
279
|
+
return;
|
|
280
|
+
const caminos = motor === "claude-code" && heredaClaveDeAnthropic(entorno()) ? ["sin-ejecucion", "con-ejecucion"] : ["unico"];
|
|
281
|
+
poner(motor, { probando: true });
|
|
282
|
+
const pruebas = [];
|
|
283
|
+
for (const camino of caminos) {
|
|
284
|
+
const controlador = new AbortController();
|
|
285
|
+
const tope = setTimeout(() => controlador.abort(), TOPE_DE_PRUEBA_MS);
|
|
286
|
+
const inicio = Date.now();
|
|
287
|
+
try {
|
|
288
|
+
const respuesta = await probarMotor({ motor, camino, entornoLimpio: limpio(entorno()), senal: controlador.signal });
|
|
289
|
+
const ok = respuestaDePruebaValida(respuesta);
|
|
290
|
+
pruebas.push({
|
|
291
|
+
camino,
|
|
292
|
+
ok,
|
|
293
|
+
detalle: ok ? `contestó «${recortar(sinUrls(respuesta), 60)}»` : `contestó otra cosa: «${recortar(sinUrls(respuesta), 100)}»`,
|
|
294
|
+
ms: Date.now() - inicio,
|
|
295
|
+
medido: ahora(),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
const detalle = controlador.signal.aborted
|
|
300
|
+
? `no contestó en ${Math.round(TOPE_DE_PRUEBA_MS / 1000)} s`
|
|
301
|
+
: recortar(sinUrls(mensajeSeguro(error instanceof Error ? error.message : String(error))));
|
|
302
|
+
pruebas.push({ camino, ok: false, detalle, ms: Date.now() - inicio, medido: ahora() });
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
clearTimeout(tope);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
poner(motor, { pruebas }, ["probando"]);
|
|
309
|
+
},
|
|
310
|
+
iniciarSesion(motor, modo) {
|
|
311
|
+
if (motor !== "claude-code" || logins.has(motor))
|
|
312
|
+
return false;
|
|
313
|
+
const bin = binarioDeClaude();
|
|
314
|
+
if (bin === undefined) {
|
|
315
|
+
poner(motor, { login: { fase: "fallo", detalle: "el SDK de Claude Code no trae binario para este sistema", desde: ahora() } });
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
let hijo;
|
|
319
|
+
try {
|
|
320
|
+
hijo = lanzar(bin, ["auth", "login", modo === "console" ? "--console" : "--claudeai"], { entorno: limpio(entorno()) });
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
poner(motor, { login: { fase: "fallo", detalle: motivoDe(error, TOPE_DE_LOGIN_MS), desde: ahora() } });
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
const desde = ahora();
|
|
327
|
+
let salida = "";
|
|
328
|
+
const vivo = {
|
|
329
|
+
hijo,
|
|
330
|
+
cancelado: false,
|
|
331
|
+
tope: setTimeout(() => {
|
|
332
|
+
vivo.cancelado = true;
|
|
333
|
+
hijo.kill();
|
|
334
|
+
cerrar("fallo", `no se terminó en ${Math.round(TOPE_DE_LOGIN_MS / 60_000)} minutos`);
|
|
335
|
+
}, TOPE_DE_LOGIN_MS),
|
|
336
|
+
};
|
|
337
|
+
logins.set(motor, vivo);
|
|
338
|
+
poner(motor, { login: { fase: "esperando", desde } });
|
|
339
|
+
let cerrado = false;
|
|
340
|
+
const cerrar = (fase, detalle) => {
|
|
341
|
+
if (cerrado)
|
|
342
|
+
return;
|
|
343
|
+
cerrado = true;
|
|
344
|
+
clearTimeout(vivo.tope);
|
|
345
|
+
logins.delete(motor);
|
|
346
|
+
poner(motor, { login: { fase, desde, ...(detalle === undefined ? {} : { detalle }) } });
|
|
347
|
+
// La sesión acaba de cambiar (o no): la foto se rehace en vez de suponerla. DESPUÉS de la
|
|
348
|
+
// medida que esté en vuelo, no unida a ella: esa empezó antes del login y diría «sin
|
|
349
|
+
// sesión» al lado de «Sesión iniciada».
|
|
350
|
+
void (medida ?? Promise.resolve())
|
|
351
|
+
.catch(() => { })
|
|
352
|
+
.then(() => servicio.medir())
|
|
353
|
+
.catch(() => { });
|
|
354
|
+
};
|
|
355
|
+
const alSalir = (trozo) => {
|
|
356
|
+
salida += trozo.toString();
|
|
357
|
+
vivo.url ??= urlDeAutorizacion(salida);
|
|
358
|
+
const login = estados.get(motor)?.login;
|
|
359
|
+
if (pideCodigo(salida) && login?.fase === "esperando" && login.pideCodigo !== true) {
|
|
360
|
+
poner(motor, { login: { ...login, pideCodigo: true } });
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
hijo.stdout?.on("data", alSalir);
|
|
364
|
+
hijo.stderr?.on("data", alSalir);
|
|
365
|
+
hijo.on("error", (error) => cerrar("fallo", motivoDe(error, TOPE_DE_LOGIN_MS)));
|
|
366
|
+
hijo.on("exit", (codigo) => {
|
|
367
|
+
if (vivo.cancelado)
|
|
368
|
+
cerrar("cancelado");
|
|
369
|
+
else if (codigo === 0)
|
|
370
|
+
cerrar("hecho");
|
|
371
|
+
else
|
|
372
|
+
cerrar("fallo", ultimaLinea(salida) ?? `terminó con código ${String(codigo)}`);
|
|
373
|
+
});
|
|
374
|
+
return true;
|
|
375
|
+
},
|
|
376
|
+
enviarCodigo(motor, codigo) {
|
|
377
|
+
const vivo = logins.get(motor);
|
|
378
|
+
const limpioDeCodigo = codigo.trim();
|
|
379
|
+
// Un código de OAuth es una línea de texto imprimible y corta: otra cosa no se le escribe
|
|
380
|
+
// a un proceso, que leería un salto de línea de más como una segunda respuesta.
|
|
381
|
+
if (vivo === undefined || limpioDeCodigo === "" || limpioDeCodigo.length > 2000 || /[\u0000-\u001f\u007f]/.test(limpioDeCodigo)) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
vivo.hijo.stdin?.write(`${limpioDeCodigo}\n`);
|
|
385
|
+
return true;
|
|
386
|
+
},
|
|
387
|
+
cancelarSesion(motor) {
|
|
388
|
+
const vivo = logins.get(motor);
|
|
389
|
+
if (vivo === undefined)
|
|
390
|
+
return false;
|
|
391
|
+
vivo.cancelado = true;
|
|
392
|
+
vivo.hijo.kill();
|
|
393
|
+
return true;
|
|
394
|
+
},
|
|
395
|
+
abrirNavegador(motor) {
|
|
396
|
+
const url = logins.get(motor)?.url;
|
|
397
|
+
if (url === undefined)
|
|
398
|
+
return false;
|
|
399
|
+
abrir(url);
|
|
400
|
+
return true;
|
|
401
|
+
},
|
|
402
|
+
abrirConsola(motor) {
|
|
403
|
+
if (motor !== "claude-code" || !admiteConsola)
|
|
404
|
+
return false;
|
|
405
|
+
const bin = binarioDeClaude();
|
|
406
|
+
if (bin === undefined)
|
|
407
|
+
return false;
|
|
408
|
+
return abrirTerminal(bin, ["auth", "login"], limpio(entorno()));
|
|
409
|
+
},
|
|
410
|
+
elegirModelo(motor, modelo) {
|
|
411
|
+
if (!MOTORES_CON_MODELO.includes(motor))
|
|
412
|
+
return false;
|
|
413
|
+
const limpioDeModelo = modelo?.trim() === "" ? undefined : modelo?.trim();
|
|
414
|
+
if (limpioDeModelo !== undefined && motivoDeModeloDeMotorInaceptable(limpioDeModelo) !== undefined)
|
|
415
|
+
return false;
|
|
416
|
+
try {
|
|
417
|
+
guardarModelo(motor, limpioDeModelo);
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
// La prueba de antes era con OTRO modelo: se quita, para que nadie lea un «✓» que ya no vale.
|
|
423
|
+
poner(motor, deModelo(motor), ["pruebas", ...(limpioDeModelo === undefined ? ["modelo"] : [])]);
|
|
424
|
+
return true;
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
return servicio;
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=motoresLocales.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motoresLocales.js","sourceRoot":"","sources":["../../../src/agent/motores/motoresLocales.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { TOPE_DE_PREGUNTAS_CONTESTADAS_SOLAS, opcionRecomendada } from "../../../core/modoDeEscritura.js";
|
|
27
27
|
import { claseDeTrabajo } from "../../../core/esfuerzo.js";
|
|
28
|
-
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
28
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
29
29
|
import { join } from "node:path";
|
|
30
30
|
import winston from "winston";
|
|
31
31
|
import { AgentThread, AgentThreadOrchestrator, EventType, NOOP_AGENT_TRACING, askUserQuestion, contextCompaction, dynamicSubAgents } from "./trueforge.js";
|
|
32
|
-
import { TOPE_DE_LLAMADAS_DEL_CONDUCTOR, TOPE_DE_LLAMADAS_DEL_ESPECIALISTA
|
|
32
|
+
import { TOPE_DE_LLAMADAS_DEL_CONDUCTOR, TOPE_DE_LLAMADAS_DEL_ESPECIALISTA } from "../../turno/resumenDeContexto.js";
|
|
33
33
|
import { crearSubagenteExterno } from "../../subagentes/subagenteExterno.js";
|
|
34
34
|
import { inventarioDelProyecto, opcionesDeSubagenteExterno } from "../../subagentes/escrituraExterna.js";
|
|
35
35
|
import { sumarConsumo, SIN_CONSUMO } from "../../subagentes/consumoExterno.js";
|
|
@@ -75,6 +75,10 @@ import { crearEsperas } from "./esperas.js";
|
|
|
75
75
|
import { conResumenSeguro } from "./resumenSeguro.js";
|
|
76
76
|
import { crearControlDeDetencion, RESUMEN_DE_RELLENO } from "./detencion.js";
|
|
77
77
|
import { crearNavegacionXone } from "../../grafo/navegacionXone.js";
|
|
78
|
+
import { crearValidarFicheroXone } from "../../grafo/validarFicheroXone.js";
|
|
79
|
+
import { topeResuelto, umbralDeCompactacion } from "../../../core/contextos.js";
|
|
80
|
+
import { parsear } from "../../../core/modelos.js";
|
|
81
|
+
import { cargar as cargarConfig } from "../../config/configEnDisco.js";
|
|
78
82
|
import { hechosDelProyectoDe } from "../../navegacion/hechosEnDisco.js";
|
|
79
83
|
import { conHechosDelProyecto } from "../../../core/hechosDelProyecto.js";
|
|
80
84
|
import { crearBusquedaRegex } from "../../grafo/busquedaRegex.js";
|
|
@@ -88,10 +92,13 @@ import { crearCriticaVisual } from "../../grafo/criticaVisual.js";
|
|
|
88
92
|
import { crearCompararCapturas } from "../../grafo/compararCapturas.js";
|
|
89
93
|
import { crearAtributosXone, NOMBRE_ATRIBUTOS_XONE } from "../../grafo/atributosXone.js";
|
|
90
94
|
import { crearDiferenciaDeCapturas } from "../../grafo/diferenciaDeCapturas.js";
|
|
91
|
-
import { crearLectorDeReferencias } from "../../grafo/lectorDeReferencias.js";
|
|
95
|
+
import { crearLectorDeReferencias, crearLocalizadorDeHtmlDeMaqueta } from "../../grafo/lectorDeReferencias.js";
|
|
96
|
+
import { cajasDeMaqueta, medidasDeImagen, viewportDeMaqueta } from "../../dispositivos/cajasDeMaqueta.js";
|
|
97
|
+
import { geometriaDeCaptura } from "../../dispositivos/geometriaEnDisco.js";
|
|
98
|
+
import { decodificarImagen } from "../../dispositivos/decodificarImagen.js";
|
|
92
99
|
import { crearDescribirImagen } from "../../grafo/describirImagen.js";
|
|
93
100
|
import { crearTraerDeLaMaquina } from "../../grafo/traerDeLaMaquina.js";
|
|
94
|
-
import { invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
|
|
101
|
+
import { describirPantalla, invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
|
|
95
102
|
import { estilosDeDisco, indiceEnDisco } from "../../navegacion/indiceEnDisco.js";
|
|
96
103
|
/** El hilo raíz de TrueForge. Se llama así en la librería y no se elige. */
|
|
97
104
|
const HILO_RAIZ = "main";
|
|
@@ -545,6 +552,25 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
545
552
|
let porModelo = {};
|
|
546
553
|
const modeloDeHilo = new Map();
|
|
547
554
|
const idDelPapel = (papel) => modelos.idDePapel?.(papel) ?? `papel ${papel}`;
|
|
555
|
+
/**
|
|
556
|
+
* El umbral de compactación del raíz, según la ventana de SU modelo (`core/contextos.ts
|
|
557
|
+
* #umbralDeCompactacion`), con la MISMA resolución que la barra (`topeResuelto`: lo fijado a mano
|
|
558
|
+
* en el proyecto, luego en el global, luego la tabla). Sin id de modelo o sin tope conocido, el
|
|
559
|
+
* 32.000 de siempre. Se lee al construir el raíz: un `/modelo` lo rehace.
|
|
560
|
+
*/
|
|
561
|
+
const umbralDelRaiz = () => {
|
|
562
|
+
const id = modelos.idDePapel?.("trabajo");
|
|
563
|
+
if (id === undefined)
|
|
564
|
+
return umbralDeCompactacion(undefined);
|
|
565
|
+
try {
|
|
566
|
+
const { proveedor, modelo } = parsear(id);
|
|
567
|
+
const { config } = cargarConfig(raiz);
|
|
568
|
+
return umbralDeCompactacion(topeResuelto(proveedor, modelo, { proyecto: config.proyecto?.contextos, global: config.global?.contextos })?.tope);
|
|
569
|
+
}
|
|
570
|
+
catch {
|
|
571
|
+
return umbralDeCompactacion(undefined);
|
|
572
|
+
}
|
|
573
|
+
};
|
|
548
574
|
const apuntarModelo = (id, cuenta, c) => {
|
|
549
575
|
porModelo = sumarPorModelo(porModelo, { [id]: { cuenta, ...c } });
|
|
550
576
|
};
|
|
@@ -613,6 +639,11 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
613
639
|
...(carpeta === undefined ? {} : { artefactos: carpeta }),
|
|
614
640
|
...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
|
|
615
641
|
});
|
|
642
|
+
const localizadorDeHtml = crearLocalizadorDeHtmlDeMaqueta({
|
|
643
|
+
raiz,
|
|
644
|
+
...(carpeta === undefined ? {} : { artefactos: carpeta }),
|
|
645
|
+
...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
|
|
646
|
+
});
|
|
616
647
|
/** El crítico y la medida, con las MISMAS piezas para quien las tenga: el raíz, y con el bucle encendido el desarrollador. */
|
|
617
648
|
const herramientasDeJuicio = () => carpeta === undefined
|
|
618
649
|
? []
|
|
@@ -620,8 +651,27 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
620
651
|
crearCriticaVisual({
|
|
621
652
|
leerArtefacto: async (nombre) => readFileSync(join(carpeta, nombre)),
|
|
622
653
|
invocar: invocarVisualConModelos({ paraPapel: (p) => modelos.paraPapel(p) }),
|
|
654
|
+
// La maqueta y la captura, cada una descrita SOLA con el mismo esquema: geometría y luego estilo.
|
|
655
|
+
describirPantalla: (imagen, existen) => describirPantalla(imagen, invocarVisualConModelos({ paraPapel: (p) => modelos.paraPapel(p) }), existen),
|
|
656
|
+
// El estilo de cada control se MIDE en sus píxeles: hace falta sacarlos de la imagen.
|
|
657
|
+
decodificar: decodificarImagen,
|
|
658
|
+
// El informe se queda junto a la captura, para poder auditar qué se le dijo al agente.
|
|
659
|
+
guardarInforme: async (nombre, informe) => {
|
|
660
|
+
mkdirSync(carpetaDeHotswap(carpeta), { recursive: true });
|
|
661
|
+
writeFileSync(join(carpetaDeHotswap(carpeta), `${nombre.replace(/\.[A-Za-z0-9]{2,4}$/, "")}.critica.txt`), informe, "utf8");
|
|
662
|
+
},
|
|
623
663
|
// La maqueta casi nunca está en /artefactos/: la trae la persona (/adjuntos/) o vive en /diseno/.
|
|
624
664
|
leerReferencia: lectorDeReferencias,
|
|
665
|
+
// La GEOMETRÍA: el árbol guardado con la captura, y las cajas de la maqueta si trae `code.html`.
|
|
666
|
+
leerGeometria: async (nombre) => geometriaDeCaptura(carpetaDeHotswap(carpeta), nombre),
|
|
667
|
+
cajasDeMaqueta: async (imagen, bytes) => {
|
|
668
|
+
const html = localizadorDeHtml(imagen);
|
|
669
|
+
const medidas = medidasDeImagen(bytes);
|
|
670
|
+
if (html === undefined || medidas === undefined)
|
|
671
|
+
return undefined;
|
|
672
|
+
const { ancho, alto } = viewportDeMaqueta(medidas.ancho, medidas.alto);
|
|
673
|
+
return cajasDeMaqueta(html, ancho, alto);
|
|
674
|
+
},
|
|
625
675
|
}),
|
|
626
676
|
// Medir la estructura contra la maqueta: la otra mitad del crítico, con el raíz como él.
|
|
627
677
|
crearCompararCapturas({ leerArtefacto: async (nombre) => readFileSync(join(carpeta, nombre)), leerReferencia: lectorDeReferencias }),
|
|
@@ -658,8 +708,12 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
658
708
|
const traerDeStitch = () => opciones.conectores !== undefined && carpeta !== undefined && conStitch
|
|
659
709
|
? [crearTraerDeStitch({ conectores: opciones.conectores, carpeta, alEscribir: anotarArtefacto })]
|
|
660
710
|
: [];
|
|
711
|
+
// ¿Está bien este .xne/.xml/.css/.js? A TODOS, el raíz incluido: es quien recibe el error que pega la persona, y
|
|
712
|
+
// sin ella lo comprobaba leyendo el fichero a ojo (soporte de APPSalud). Pura y de lectura.
|
|
713
|
+
const validarFichero = () => crearValidarFicheroXone(backend);
|
|
661
714
|
const propiasDelRaiz = [
|
|
662
715
|
navegacion(),
|
|
716
|
+
validarFichero(),
|
|
663
717
|
atributos,
|
|
664
718
|
describirImagen(),
|
|
665
719
|
...herramientasDeJuicio(),
|
|
@@ -669,6 +723,7 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
669
723
|
const propiasDe = (agente) => [
|
|
670
724
|
crearBusquedaRegex(backend),
|
|
671
725
|
navegacion(),
|
|
726
|
+
validarFichero(),
|
|
672
727
|
atributos,
|
|
673
728
|
describirImagen(),
|
|
674
729
|
...(carpeta !== undefined && (agente.escribeEn ?? []).length > 0
|
|
@@ -731,6 +786,18 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
731
786
|
};
|
|
732
787
|
const razonamientoDeSalida = (salida) => razonamientoPendiente.get(salida)?.shift();
|
|
733
788
|
const llm = modeloParaTrueforge({ modelo: () => clienteDe("papel:trabajo:", () => modelos.paraPapel("trabajo")), senal: () => aborto?.signal, alRazonar });
|
|
789
|
+
/**
|
|
790
|
+
* El modelo de la COMPACTACIÓN: el mismo del raíz, con el pensamiento APAGADO donde el modelo lo
|
|
791
|
+
* admite (`core/esfuerzo.ts#pensamientoAplicable`: hoy DeepSeek; en los demás no se manda nada que
|
|
792
|
+
* no esté medido, así que se quedan como el raíz). Resumir no necesita razonar, y medido en dos
|
|
793
|
+
* sesiones de soporte la compactación sí razonaba: hasta 13.650 tokens de razonamiento para un
|
|
794
|
+
* resumen de ~4.000, 72 s de los 164 del turno, y en otro, 13 compactaciones en 30 min.
|
|
795
|
+
*/
|
|
796
|
+
const llmDeCompactacion = modeloParaTrueforge({
|
|
797
|
+
modelo: () => clienteDe("papel:trabajo:compactacion", () => modelos.paraPapel("trabajo", undefined, undefined, "apagado")),
|
|
798
|
+
senal: () => aborto?.signal,
|
|
799
|
+
alRazonar,
|
|
800
|
+
});
|
|
734
801
|
/**
|
|
735
802
|
* El hilo de un hijo EXTERNO: un `AgentThread` normal con UNA llamada, cuyo «modelo» es el
|
|
736
803
|
* producto (`modeloExterno.ts`). Sin tools, sin capabilities y sin compactación: el bucle vive
|
|
@@ -1006,15 +1073,16 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
1006
1073
|
capacidadDeInformes,
|
|
1007
1074
|
]),
|
|
1008
1075
|
/**
|
|
1009
|
-
* **La conversación se RESUME
|
|
1010
|
-
* sin
|
|
1011
|
-
*
|
|
1012
|
-
*
|
|
1013
|
-
* capability—, que no se
|
|
1076
|
+
* **La conversación se RESUME a un umbral que depende de la ventana del modelo**
|
|
1077
|
+
* (`umbralDelRaiz`): sin compactar, cada turno reenviaba la sesión entera; con el 32.000
|
|
1078
|
+
* fijo de deepagents, DeepSeek compactaba cada dos o tres lecturas. La compactación de
|
|
1079
|
+
* TrueForge sustituye el contexto ENTERO por el resumen, y por eso las instrucciones van
|
|
1080
|
+
* en el prompt de sistema —aquí `instruction`, en un hijo su capability—, que no se
|
|
1081
|
+
* compacta. Y resume con el pensamiento APAGADO (`llmDeCompactacion`).
|
|
1014
1082
|
*/
|
|
1015
1083
|
contextCompaction({
|
|
1016
|
-
definition: { ...definicion, modelClient: conResumenSeguro(
|
|
1017
|
-
compactionThresholdTokens:
|
|
1084
|
+
definition: { ...definicion, modelClient: conResumenSeguro(llmDeCompactacion, (t) => anotarPaso("trueforge.compactacion", t)()) },
|
|
1085
|
+
compactionThresholdTokens: umbralDelRaiz(),
|
|
1018
1086
|
}),
|
|
1019
1087
|
// `ask_user_question`, SOLO en el raíz —la librería tampoco se la da a un hijo—: es el
|
|
1020
1088
|
// único que tiene a una persona delante.
|