xonecode 0.28.0 → 0.31.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.
@@ -15,9 +15,10 @@
15
15
  * reintento de un minuto de `lanzarYComprobar` es para un framework que ARRANCA, no para uno que
16
16
  * no está.
17
17
  * - **`result:true` no es «aplicado»**: lo que se afirma es que la app CONTESTA su árbol después.
18
- * - **Relanzar es `lanzarYComprobar`, y solo a petición**: un `launchApplication` suelto sobre una
19
- * app viva la TUMBA (medido), y `lanzarYComprobar` solo reenvía detrás de una lectura que dice
20
- * «no está».
18
+ * - **Lo que solo se lee al cargar la app (CSS, `app.ini`, `app.xml`) RELANZA la app**, por
19
+ * `lanzarYComprobar`: un `launchApplication` suelto sobre una app viva la TUMBA (medido), y
20
+ * `lanzarYComprobar` solo reenvía detrás de una lectura que dice «no está». Se probó todo lo del
21
+ * canal para hacerlo sin relanzar y nada cambia el estilo (ver `docs/DECISIONES.md`).
21
22
  */
22
23
  import { execFile } from "node:child_process";
23
24
  import { existsSync } from "node:fs";
@@ -53,8 +54,48 @@ export async function recargarEnAparato(peticion, deps = {}) {
53
54
  });
54
55
  if (subida.result !== true)
55
56
  return { estado: "fallo", clase, motivo: `uploadFile: ${decirDe(subida)}` };
56
- if (clase === "relanzar")
57
- return { estado: "relanzar", clase };
57
+ if (clase === "css") {
58
+ // Un CSS se recarga en caliente, sin relanzar. Dos caminos, los dos MEDIDOS en el emulador:
59
+ // - el comando `loadCssFile` del canal (framework 5.0.5.7dev en adelante): sustituye la hoja en
60
+ // su sitio de la cascada y relayouta solo;
61
+ // - en un framework anterior, que contesta `Unknown command`, las funciones de XOne por
62
+ // `runScript` (`appData.unloadCssFile` + `loadCssFile`) y un `refresh`, sin el cual no se ve.
63
+ // Lo que NO funciona, también medido: `setCssAttribute`, `relayout`, `refresh` o
64
+ // `loadCollection` solos. Si nada aplica (un nombre que no encaja), se cae a relanzar.
65
+ const nombre = peticion.ruta.replace(/^\/+/, "");
66
+ const tabla = codificacionParaElAparato(peticion.bytes);
67
+ const nativo = await pedir("loadCssFile", { fileName: nombre, encoding: tabla });
68
+ let recargado = nativo.result === true;
69
+ if (!recargado && /Unknown command/i.test(decirDe(nativo))) {
70
+ const script = `appData.unloadCssFile(${JSON.stringify(nombre)}); appData.loadCssFile(${JSON.stringify(nombre)}, ${JSON.stringify(tabla)}); return "ok";`;
71
+ const porScript = await pedir("runScript", {
72
+ scriptLanguage: "javascript",
73
+ scriptText: Buffer.from(script, "utf8").toString("base64"),
74
+ });
75
+ if (porScript.result === true) {
76
+ await pedir("refresh");
77
+ recargado = true;
78
+ }
79
+ }
80
+ if (recargado) {
81
+ const despues = await pedir("getAllElements", { format: "xone" });
82
+ if (estaViva(despues))
83
+ return { estado: "aplicada", clase };
84
+ }
85
+ }
86
+ if (clase === "relanzar" || clase === "css") {
87
+ // `app.ini`, `app.xml` y los mappings solo se leen al CARGAR la app; y un CSS cuyo script falló.
88
+ // Se relanza, por el camino que no tumba una app viva.
89
+ cliente.cerrar();
90
+ cliente = undefined;
91
+ const arranque = await lanzarYComprobar(peticion.app, {
92
+ destino: destinoDe(peticion.puerto),
93
+ ...(deps.abrirSocket === undefined ? {} : { abrirSocket: deps.abrirSocket }),
94
+ });
95
+ return arranque.viva
96
+ ? { estado: "relanzada", clase }
97
+ : { estado: "fallo", clase, motivo: `se relanzó y no volvió: ${arranque.motivo ?? "sin motivo"}` };
98
+ }
58
99
  // 2. Aplicar. Una colección va a memoria en UTF-8 con su prólogo diciéndolo (medido: con los
59
100
  // bytes Latin-1 cada tilde salía doble); un include se lee del DISCO, en la tabla de sus bytes.
60
101
  const aplicado = clase === "coleccion"
@@ -1 +1 @@
1
- {"version":3,"file":"recargaEnAparato.js","sourceRoot":"","sources":["../../../src/agent/dispositivos/recargaEnAparato.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recargaEnAparato.js","sourceRoot":"","sources":["../../../src/agent/dispositivos/recargaEnAparato.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import { tool } from "@langchain/core/tools";
2
+ import { z } from "zod";
3
+ import { comprobarCss } from "../../core/cssBienFormado.js";
4
+ import { comprobarJs } from "../../core/jsParaRhino.js";
5
+ import { comprobarXml } from "../../core/xmlBienFormado.js";
6
+ import { puedeLeerRuta } from "./perfiles.js";
7
+ /**
8
+ * `validar_fichero_xone`: ¿está bien este `.xne`, `.xml` (el `app.xml`), `.css` o `.js`? Una respuesta
9
+ * exacta en vez de leer el fichero a ojo. Cada extensión con su comprobador puro de `core/`:
10
+ * `comprobarXml` (bien formado), `comprobarCss` (estructura de la hoja, con la gramática de XOne) y
11
+ * `comprobarJs` (lo que lee Rhino, el motor de Android: `acorn` a ES2015 más la rodaja medida que le
12
+ * falta).
13
+ *
14
+ * Existe por un turno real (soporte de APPSalud): la persona pegó un error del parser de Studio
15
+ * («'name' is an unexpected token…, Line 381») y el agente, sin forma de comprobarlo, se pasó
16
+ * minutos releyendo un fichero que estaba BIEN —lo dijo a los dos minutos y no se lo creyó—.
17
+ *
18
+ * - **Sin llamar a nadie**: el comprobador es puro (`core/xmlBienFormado.ts`), ni simulador ni
19
+ * linter ni red.
20
+ * - **Lee por el backend** (`readRaw`), así que hereda la codificación del fichero, las vistas
21
+ * aplanadas y el resto de guardas; y **reaplica `puedeLeerRuta` a mano**, porque una tool de
22
+ * LangChain añadida por xonecode no pasa por el middleware de permisos.
23
+ * - **Solo lectura**: no corrige nada. Y su descripción dice qué significa un «bien formado»
24
+ * frente a un error que alguien ha visto: que ese error viene de OTRA copia del fichero.
25
+ */
26
+ export const NOMBRE_VALIDAR_FICHERO_XONE = "validar_fichero_xone";
27
+ /** Cuántos ficheros como mucho en una pasada sobre una carpeta. */
28
+ export const TOPE_DE_FICHEROS_A_VALIDAR = 300;
29
+ const ESQUEMA = z.object({
30
+ path: z
31
+ .string()
32
+ .min(1)
33
+ .default("/")
34
+ .describe("Un fichero .xne, .xml, .css o .js, o una carpeta para revisar todos los que cuelgan de ella (por omisión, el proyecto entero)"),
35
+ });
36
+ const VALIDABLE = /\.(xne|xml|css|js)$/i;
37
+ /** El comprobador de cada extensión. */
38
+ function comprobar(ruta, texto) {
39
+ const ext = ruta.slice(ruta.lastIndexOf(".")).toLowerCase();
40
+ if (ext === ".css")
41
+ return comprobarCss(texto);
42
+ if (ext === ".js")
43
+ return comprobarJs(texto);
44
+ return comprobarXml(texto);
45
+ }
46
+ export function crearValidarFicheroXone(backend) {
47
+ return tool(async (entrada) => {
48
+ const ruta = entrada.path.startsWith("/") ? entrada.path : `/${entrada.path}`;
49
+ let candidatos;
50
+ if (VALIDABLE.test(ruta)) {
51
+ if (!puedeLeerRuta(ruta))
52
+ return `No se puede leer ${ruta}.`;
53
+ candidatos = [ruta];
54
+ }
55
+ else {
56
+ const listado = await backend.glob("**/*.{xne,xml,css,js}", ruta);
57
+ if (listado.error)
58
+ return `No se pudo listar ${ruta}: ${listado.error}`;
59
+ candidatos = (listado.files ?? [])
60
+ .filter((f) => !f.is_dir && VALIDABLE.test(f.path) && puedeLeerRuta(f.path))
61
+ .map((f) => f.path);
62
+ if (candidatos.length === 0)
63
+ return `No hay ficheros .xne, .xml, .css ni .js en ${ruta}.`;
64
+ }
65
+ const recortado = candidatos.length > TOPE_DE_FICHEROS_A_VALIDAR;
66
+ const malos = [];
67
+ const sinLeer = [];
68
+ let bien = 0;
69
+ for (const fichero of candidatos.slice(0, TOPE_DE_FICHEROS_A_VALIDAR)) {
70
+ const leido = await backend.readRaw(fichero);
71
+ if (leido.error || !leido.data || typeof leido.data.content !== "string") {
72
+ sinLeer.push(`${fichero}: ${leido.error ?? "no se pudo leer"}`);
73
+ continue;
74
+ }
75
+ const r = comprobar(fichero, leido.data.content);
76
+ if (r.ok) {
77
+ bien += 1;
78
+ continue;
79
+ }
80
+ const linea = leido.data.content.replace(/^/, "").split(/\r?\n/)[r.linea - 1] ?? "";
81
+ malos.push(`${fichero}:${r.linea}:${r.columna}: ${r.motivo}\n ${linea.trim().slice(0, 200)}`);
82
+ }
83
+ const partes = [];
84
+ if (malos.length === 0 && sinLeer.length === 0) {
85
+ partes.push(candidatos.length === 1
86
+ ? `${candidatos[0]} está bien.`
87
+ : `Los ${bien} ficheros están bien.`);
88
+ }
89
+ else {
90
+ if (malos.length > 0)
91
+ partes.push(`Con errores (${malos.length}):\n${malos.join("\n")}`);
92
+ if (bien > 0)
93
+ partes.push(`Bien: ${bien}.`);
94
+ if (sinLeer.length > 0)
95
+ partes.push(`Sin poder leer (${sinLeer.length}):\n${sinLeer.join("\n")}`);
96
+ }
97
+ if (recortado)
98
+ partes.push(`Se revisaron los primeros ${TOPE_DE_FICHEROS_A_VALIDAR} de ${candidatos.length}: acota la carpeta.`);
99
+ return partes.join("\n\n");
100
+ }, {
101
+ name: NOMBRE_VALIDAR_FICHERO_XONE,
102
+ description: "Comprueba un fichero XOne del proyecto, o todos los de una carpeta, como lo haría su parser: un .xne o .xml " +
103
+ "(el app.xml) bien formado —etiquetas, atributos con su «=» y comillas, comentarios, entidades—; un .css con " +
104
+ "su estructura —llaves, comentarios /* */ y //, declaraciones con «:»—; un .js que pueda leer Rhino, el motor " +
105
+ "de Android (ES5 más arrow, let/const, destructuring y for…of; NO template literals, class, spread, valores " +
106
+ "por defecto, ?. ni ??). Contesta «está bien» o fichero, línea, columna y motivo. Úsala ANTES de leer un " +
107
+ "fichero a ojo cuando alguien te pase un error de parsing, y después de escribir uno. Si dice que está bien, " +
108
+ "el fichero del proyecto está bien: un error de parsing que alguien ha visto viene de OTRA copia (la de Studio " +
109
+ "tras una subida, la del aparato); dilo así en vez de seguir releyendo. No comprueba qué atributos o " +
110
+ "propiedades existen en XOne (para eso, xone_atributos).",
111
+ schema: ESQUEMA,
112
+ });
113
+ }
114
+ //# sourceMappingURL=validarFicheroXone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validarFicheroXone.js","sourceRoot":"","sources":["../../../src/agent/grafo/validarFicheroXone.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,7 @@ import { existsSync, readdirSync, readFileSync } 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, UMBRAL_RESUMEN_TOKENS } from "../../turno/resumenDeContexto.js";
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";
@@ -545,6 +549,25 @@ export async function abrirSesionTrueforge(opciones) {
545
549
  let porModelo = {};
546
550
  const modeloDeHilo = new Map();
547
551
  const idDelPapel = (papel) => modelos.idDePapel?.(papel) ?? `papel ${papel}`;
552
+ /**
553
+ * El umbral de compactación del raíz, según la ventana de SU modelo (`core/contextos.ts
554
+ * #umbralDeCompactacion`), con la MISMA resolución que la barra (`topeResuelto`: lo fijado a mano
555
+ * en el proyecto, luego en el global, luego la tabla). Sin id de modelo o sin tope conocido, el
556
+ * 32.000 de siempre. Se lee al construir el raíz: un `/modelo` lo rehace.
557
+ */
558
+ const umbralDelRaiz = () => {
559
+ const id = modelos.idDePapel?.("trabajo");
560
+ if (id === undefined)
561
+ return umbralDeCompactacion(undefined);
562
+ try {
563
+ const { proveedor, modelo } = parsear(id);
564
+ const { config } = cargarConfig(raiz);
565
+ return umbralDeCompactacion(topeResuelto(proveedor, modelo, { proyecto: config.proyecto?.contextos, global: config.global?.contextos })?.tope);
566
+ }
567
+ catch {
568
+ return umbralDeCompactacion(undefined);
569
+ }
570
+ };
548
571
  const apuntarModelo = (id, cuenta, c) => {
549
572
  porModelo = sumarPorModelo(porModelo, { [id]: { cuenta, ...c } });
550
573
  };
@@ -658,8 +681,12 @@ export async function abrirSesionTrueforge(opciones) {
658
681
  const traerDeStitch = () => opciones.conectores !== undefined && carpeta !== undefined && conStitch
659
682
  ? [crearTraerDeStitch({ conectores: opciones.conectores, carpeta, alEscribir: anotarArtefacto })]
660
683
  : [];
684
+ // ¿Está bien este .xne/.xml/.css/.js? A TODOS, el raíz incluido: es quien recibe el error que pega la persona, y
685
+ // sin ella lo comprobaba leyendo el fichero a ojo (soporte de APPSalud). Pura y de lectura.
686
+ const validarFichero = () => crearValidarFicheroXone(backend);
661
687
  const propiasDelRaiz = [
662
688
  navegacion(),
689
+ validarFichero(),
663
690
  atributos,
664
691
  describirImagen(),
665
692
  ...herramientasDeJuicio(),
@@ -669,6 +696,7 @@ export async function abrirSesionTrueforge(opciones) {
669
696
  const propiasDe = (agente) => [
670
697
  crearBusquedaRegex(backend),
671
698
  navegacion(),
699
+ validarFichero(),
672
700
  atributos,
673
701
  describirImagen(),
674
702
  ...(carpeta !== undefined && (agente.escribeEn ?? []).length > 0
@@ -731,6 +759,18 @@ export async function abrirSesionTrueforge(opciones) {
731
759
  };
732
760
  const razonamientoDeSalida = (salida) => razonamientoPendiente.get(salida)?.shift();
733
761
  const llm = modeloParaTrueforge({ modelo: () => clienteDe("papel:trabajo:", () => modelos.paraPapel("trabajo")), senal: () => aborto?.signal, alRazonar });
762
+ /**
763
+ * El modelo de la COMPACTACIÓN: el mismo del raíz, con el pensamiento APAGADO donde el modelo lo
764
+ * admite (`core/esfuerzo.ts#pensamientoAplicable`: hoy DeepSeek; en los demás no se manda nada que
765
+ * no esté medido, así que se quedan como el raíz). Resumir no necesita razonar, y medido en dos
766
+ * sesiones de soporte la compactación sí razonaba: hasta 13.650 tokens de razonamiento para un
767
+ * resumen de ~4.000, 72 s de los 164 del turno, y en otro, 13 compactaciones en 30 min.
768
+ */
769
+ const llmDeCompactacion = modeloParaTrueforge({
770
+ modelo: () => clienteDe("papel:trabajo:compactacion", () => modelos.paraPapel("trabajo", undefined, undefined, "apagado")),
771
+ senal: () => aborto?.signal,
772
+ alRazonar,
773
+ });
734
774
  /**
735
775
  * El hilo de un hijo EXTERNO: un `AgentThread` normal con UNA llamada, cuyo «modelo» es el
736
776
  * producto (`modeloExterno.ts`). Sin tools, sin capabilities y sin compactación: el bucle vive
@@ -1006,15 +1046,16 @@ export async function abrirSesionTrueforge(opciones) {
1006
1046
  capacidadDeInformes,
1007
1047
  ]),
1008
1048
  /**
1009
- * **La conversación se RESUME al mismo umbral que deepagents** (`UMBRAL_RESUMEN_TOKENS`):
1010
- * sin esto no se compactaba nunca y cada turno reenviaba la sesión entera. La
1011
- * compactación de TrueForge sustituye el contexto ENTERO por el resumen, y por eso las
1012
- * instrucciones van en el prompt de sistema —aquí `instruction`, en un hijo su
1013
- * capability—, que no se compacta.
1049
+ * **La conversación se RESUME a un umbral que depende de la ventana del modelo**
1050
+ * (`umbralDelRaiz`): sin compactar, cada turno reenviaba la sesión entera; con el 32.000
1051
+ * fijo de deepagents, DeepSeek compactaba cada dos o tres lecturas. La compactación de
1052
+ * TrueForge sustituye el contexto ENTERO por el resumen, y por eso las instrucciones van
1053
+ * en el prompt de sistema —aquí `instruction`, en un hijo su capability—, que no se
1054
+ * compacta. Y resume con el pensamiento APAGADO (`llmDeCompactacion`).
1014
1055
  */
1015
1056
  contextCompaction({
1016
- definition: { ...definicion, modelClient: conResumenSeguro(definicion.modelClient, (t) => anotarPaso("trueforge.compactacion", t)()) },
1017
- compactionThresholdTokens: UMBRAL_RESUMEN_TOKENS,
1057
+ definition: { ...definicion, modelClient: conResumenSeguro(llmDeCompactacion, (t) => anotarPaso("trueforge.compactacion", t)()) },
1058
+ compactionThresholdTokens: umbralDelRaiz(),
1018
1059
  }),
1019
1060
  // `ask_user_question`, SOLO en el raíz —la librería tampoco se la da a un hijo—: es el
1020
1061
  // único que tiene a una persona delante.