xonecode 0.11.0 → 0.13.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/index-D8kdTP0Z.css +1 -0
- package/apps/web/dist/assets/index-a1EvXQj9.js +485 -0
- package/apps/web/dist/assets/{php-DPbDT8rX.js → php-qXN69lAY.js} +1 -1
- package/apps/web/dist/assets/{ruby-Bfvws9R8.js → ruby-Cxx7RgZA.js} +1 -1
- package/apps/web/dist/iconos/conectores/deepwiki.png +0 -0
- package/apps/web/dist/iconos/conectores/jira.png +0 -0
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/conectores/conectoresEnDisco.js +188 -0
- package/dist/agent/conectores/conectoresEnDisco.js.map +1 -0
- package/dist/agent/conectores/proveedorDeConector.js +56 -0
- package/dist/agent/conectores/proveedorDeConector.js.map +1 -0
- package/dist/agent/conectores/servicioDeConectores.js +496 -0
- package/dist/agent/conectores/servicioDeConectores.js.map +1 -0
- package/dist/agent/config/catalogoModelos.js +2 -0
- package/dist/agent/config/catalogoModelos.js.map +1 -1
- package/dist/agent/config/modelos.js +27 -0
- package/dist/agent/config/modelos.js.map +1 -1
- package/dist/agent/config/settingsEnDisco.js +16 -0
- package/dist/agent/config/settingsEnDisco.js.map +1 -1
- package/dist/agent/dispositivos/procesosEnMaquina.js +24 -2
- package/dist/agent/dispositivos/procesosEnMaquina.js.map +1 -1
- package/dist/agent/grafo/ejecucionCancelable.js +117 -0
- package/dist/agent/grafo/ejecucionCancelable.js.map +1 -0
- package/dist/agent/grafo/incorporarAdjunto.js +262 -0
- package/dist/agent/grafo/incorporarAdjunto.js.map +1 -0
- package/dist/agent/grafo/perfiles.js +12 -5
- package/dist/agent/grafo/perfiles.js.map +1 -1
- package/dist/agent/grafo/proyecto.js +53 -18
- package/dist/agent/grafo/proyecto.js.map +1 -1
- package/dist/agent/grafo/xoneAgent.js +25 -0
- package/dist/agent/grafo/xoneAgent.js.map +1 -1
- package/dist/agent/motores/trueforge/capacidades.js +69 -4
- package/dist/agent/motores/trueforge/capacidades.js.map +1 -1
- package/dist/agent/motores/trueforge/detencion.js +138 -0
- package/dist/agent/motores/trueforge/detencion.js.map +1 -0
- package/dist/agent/motores/trueforge/modeloLangchain.js +36 -4
- package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -1
- package/dist/agent/motores/trueforge/notas.js +49 -0
- package/dist/agent/motores/trueforge/notas.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +100 -3
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
- package/dist/agent/sesiones/adjuntosDeSesion.js +235 -0
- package/dist/agent/sesiones/adjuntosDeSesion.js.map +1 -0
- package/dist/agent/subagentes/agentesEnDisco.js +4 -0
- package/dist/agent/subagentes/agentesEnDisco.js.map +1 -1
- package/dist/agent/trazaDeErroresEnDisco.js +12 -4
- package/dist/agent/trazaDeErroresEnDisco.js.map +1 -1
- package/dist/agent/turno/depuracion.js +27 -0
- package/dist/agent/turno/depuracion.js.map +1 -0
- package/dist/agent/turno/diagnosticoDeTools.js +7 -1
- package/dist/agent/turno/diagnosticoDeTools.js.map +1 -1
- package/dist/agent/turno/informeDeTraza.js +2 -1
- package/dist/agent/turno/informeDeTraza.js.map +1 -1
- package/dist/agent/turno/interrupts.js +13 -0
- package/dist/agent/turno/interrupts.js.map +1 -1
- package/dist/agent/turno/resumenDeTool.js +4 -0
- package/dist/agent/turno/resumenDeTool.js.map +1 -1
- package/dist/agent/turno/turnoReal.js +9 -2
- package/dist/agent/turno/turnoReal.js.map +1 -1
- package/dist/cli/main.js +52 -10
- package/dist/cli/main.js.map +1 -1
- package/dist/core/actos.js.map +1 -1
- package/dist/core/adjuntos.js +72 -14
- package/dist/core/adjuntos.js.map +1 -1
- package/dist/core/conectores.js +191 -0
- package/dist/core/conectores.js.map +1 -0
- package/dist/core/entrega.js.map +1 -1
- package/dist/core/modelos.js +23 -1
- package/dist/core/modelos.js.map +1 -1
- package/dist/core/settings.js +57 -0
- package/dist/core/settings.js.map +1 -1
- package/dist/web/servidor/arranque.js +336 -6
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/consolaWeb.js +29 -3
- package/dist/web/servidor/consolaWeb.js.map +1 -1
- package/dist/web/servidor/servidor.js +16 -1
- package/dist/web/servidor/servidor.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/dist/web/servidor/vestibulo.js +122 -11
- package/dist/web/servidor/vestibulo.js.map +1 -1
- package/dist/web/servidor/visorOpenui.js +25 -3
- package/dist/web/servidor/visorOpenui.js.map +1 -1
- package/package.json +1 -1
- package/apps/web/dist/assets/index-BAyybSz-.css +0 -1
- package/apps/web/dist/assets/index-BNCMVjWv.js +0 -485
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DETENER y replanificar (IXCODE-4): la persona pulsa el botón mientras el agente trabaja, los
|
|
3
|
+
* especialistas que estaban en marcha cierran con un resumen de lo hecho y lo que les quedaba, y
|
|
4
|
+
* el orquestador recibe esos resúmenes con el mensaje de la persona y replanifica.
|
|
5
|
+
*
|
|
6
|
+
* **No es una `Nota`, y a propósito**: una nota se entrega a CADA hilo como encargo (`notas.ts`),
|
|
7
|
+
* y una orden de parar repartida así haría que el hijo parase y el raíz… volviera a encargar lo
|
|
8
|
+
* mismo. Aquí cada destinatario recibe SU texto: el hijo, «para y resume»; el raíz, «replanifica
|
|
9
|
+
* sin repetir lo hecho».
|
|
10
|
+
*
|
|
11
|
+
* **A quién se detiene**: a los hijos nacidos de una llamada del raíz que empezó ANTES de pulsar.
|
|
12
|
+
* No basta «los vivos al pulsar»: si se pulsa mientras el raíz está decidiendo delegar, el hijo
|
|
13
|
+
* que sale de esa decisión nace después, pero de un plan que la persona ya no quiere. Y los que
|
|
14
|
+
* el raíz delegue DESPUÉS de leer la orden corren normal —son el plan nuevo—.
|
|
15
|
+
*
|
|
16
|
+
* **Cómo para un hijo, sin tocar la librería**: la orden entra por `preLLMProcessors` antes de su
|
|
17
|
+
* siguiente llamada, y SU modelo (`modeloParaTrueforge`, construido por hilo en `crearHijo`) tira
|
|
18
|
+
* las tool calls de esa respuesta: una respuesta sin tool calls cierra el hilo con normalidad
|
|
19
|
+
* (`AGENT_DONE`) y su texto le llega al padre como resultado de `create_sub_agent`. Se FILTRA lo
|
|
20
|
+
* que devuelve el modelo, no se le quitan las tools: con el historial lleno de llamadas, algún
|
|
21
|
+
* proveedor rechaza una petición sin la definición de tools.
|
|
22
|
+
*
|
|
23
|
+
* **Y una llamada EN CURSO se corta** (`corte`): medido con el botón, el analista estaba dentro de
|
|
24
|
+
* una llamada de 60 s generando un informe entero cuando se pulsó, y sin corte esa llamada acababa
|
|
25
|
+
* escribiéndolo. Cada hijo lleva su `AbortController`, que aborta SOLO su stream; el modelo del
|
|
26
|
+
* hijo lo captura y pide el resumen en el acto (`modeloLangchain.ts#corte`). Lo que NO se corta:
|
|
27
|
+
* un comando de shell en curso, que termina primero —la orden llega en la llamada siguiente—.
|
|
28
|
+
*/
|
|
29
|
+
/** Lo que llega al padre si el hijo, tras filtrar, no dejó texto. */
|
|
30
|
+
export const RESUMEN_DE_RELLENO = "[Detenido a petición de la persona antes de poder resumir lo hecho.]";
|
|
31
|
+
const cita = (texto) => (texto.trim() === "" ? "" : `: «${texto.trim()}»`);
|
|
32
|
+
export function textoDeDetencionParaHijo(texto) {
|
|
33
|
+
return (`[La persona ha pulsado DETENER${cita(texto)}. Para aquí: no hagas ninguna llamada más —no se ejecutaría—. ` +
|
|
34
|
+
"Contesta YA a quien te delegó con: (1) lo que has hecho y dónde (ficheros leídos o escritos, hallazgos con su fichero), " +
|
|
35
|
+
"(2) lo que te quedaba por hacer. Con eso se replanifica, y lo que digas como hecho no se repetirá.]");
|
|
36
|
+
}
|
|
37
|
+
export function textoDeDetencionParaRaiz(texto) {
|
|
38
|
+
return (`[La persona ha pulsado DETENER y replanificar mientras trabajabas${cita(texto)}. ` +
|
|
39
|
+
"Los especialistas que estaban trabajando han parado; lo que hicieron y lo que les quedaba está en su respuesta. " +
|
|
40
|
+
"Replanifica con esto: lo que ya está hecho NO se repite, y si vuelves a delegar, el encargo nuevo dice qué está hecho y qué cambia.]");
|
|
41
|
+
}
|
|
42
|
+
/** Lleva la cuenta que decide a quién se detiene: cuántas llamadas lleva el raíz, y de cuál nació
|
|
43
|
+
* cada hijo. Uno por sesión; `reiniciar` al empezar cada turno. */
|
|
44
|
+
export function crearControlDeDetencion(hiloRaiz) {
|
|
45
|
+
let llamadasDelRaiz = 0;
|
|
46
|
+
const nacimiento = new Map();
|
|
47
|
+
/** El corte de cada hijo: aborta SOLO su stream en curso. */
|
|
48
|
+
const cortes = new Map();
|
|
49
|
+
let detencion;
|
|
50
|
+
const debeParar = (threadId) => {
|
|
51
|
+
if (detencion === undefined || threadId === hiloRaiz)
|
|
52
|
+
return false;
|
|
53
|
+
const n = nacimiento.get(threadId);
|
|
54
|
+
return n !== undefined && n <= detencion.hastaLlamadaDelRaiz;
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
reiniciar() {
|
|
58
|
+
llamadasDelRaiz = 0;
|
|
59
|
+
nacimiento.clear();
|
|
60
|
+
cortes.clear();
|
|
61
|
+
detencion = undefined;
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Cuántos hijos trabajan a la vez AHORA: los nacidos de la última llamada del raíz. Mientras un
|
|
65
|
+
* hijo vive, el raíz espera su resultado y no vuelve a llamar al modelo, así que lo nacido de
|
|
66
|
+
* llamadas anteriores ya terminó. Lo usa el reparto de notas (`notas.ts`).
|
|
67
|
+
*/
|
|
68
|
+
hijosVivos() {
|
|
69
|
+
let n = 0;
|
|
70
|
+
for (const nacida of nacimiento.values())
|
|
71
|
+
if (nacida === llamadasDelRaiz)
|
|
72
|
+
n += 1;
|
|
73
|
+
return n;
|
|
74
|
+
},
|
|
75
|
+
/** Al crear un hijo: nace de la llamada del raíz en curso. */
|
|
76
|
+
nacio(threadId) {
|
|
77
|
+
nacimiento.set(threadId, llamadasDelRaiz);
|
|
78
|
+
cortes.set(threadId, new AbortController());
|
|
79
|
+
},
|
|
80
|
+
detener(texto) {
|
|
81
|
+
// Una segunda pulsación en el mismo turno alcanza a lo que haya nacido desde entonces; quien
|
|
82
|
+
// ya recibió la orden no la recibe otra vez. Su texto se JUNTA solo con lo que el raíz aún no
|
|
83
|
+
// leyó: medido, juntarlo con lo ya leído lo volvía a mandar —y tras Parar, como un turno
|
|
84
|
+
// nuevo que nadie pidió—.
|
|
85
|
+
const pendiente = detencion === undefined || detencion.raizAvisado ? "" : detencion.texto;
|
|
86
|
+
detencion = {
|
|
87
|
+
texto: [pendiente, texto].filter((t) => t.trim() !== "").join("\n\n"),
|
|
88
|
+
hastaLlamadaDelRaiz: llamadasDelRaiz,
|
|
89
|
+
avisados: detencion?.avisados ?? new Set(),
|
|
90
|
+
raizAvisado: false,
|
|
91
|
+
};
|
|
92
|
+
// Y a quien esté a mitad de una llamada, se le corta: pedirá el resumen en el acto.
|
|
93
|
+
for (const [hilo, control] of cortes)
|
|
94
|
+
if (debeParar(hilo) && !detencion.avisados.has(hilo))
|
|
95
|
+
control.abort();
|
|
96
|
+
},
|
|
97
|
+
/** Para el modelo de un hijo, al empezar cada llamada: su señal de corte y la orden que se le da
|
|
98
|
+
* si se corta. Darla lo cuenta como avisado —no la recibe otra vez por el procesador—. */
|
|
99
|
+
corte(threadId) {
|
|
100
|
+
const control = cortes.get(threadId);
|
|
101
|
+
if (control === undefined)
|
|
102
|
+
return undefined;
|
|
103
|
+
return {
|
|
104
|
+
senal: control.signal,
|
|
105
|
+
orden: () => {
|
|
106
|
+
detencion.avisados.add(threadId);
|
|
107
|
+
return textoDeDetencionParaHijo(detencion.texto);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
/** Para el modelo de un hijo: si ya recibió la orden, su respuesta no puede llamar tools. */
|
|
112
|
+
soloTexto(threadId) {
|
|
113
|
+
return detencion?.avisados.has(threadId) === true;
|
|
114
|
+
},
|
|
115
|
+
/** Lo que se le mete a ESE hilo antes de su llamada, si algo. Cuenta las llamadas del raíz. */
|
|
116
|
+
antesDeLlamar(threadId) {
|
|
117
|
+
if (threadId === hiloRaiz) {
|
|
118
|
+
llamadasDelRaiz += 1;
|
|
119
|
+
if (detencion === undefined || detencion.raizAvisado)
|
|
120
|
+
return undefined;
|
|
121
|
+
detencion.raizAvisado = true;
|
|
122
|
+
return textoDeDetencionParaRaiz(detencion.texto);
|
|
123
|
+
}
|
|
124
|
+
if (!debeParar(threadId) || detencion.avisados.has(threadId))
|
|
125
|
+
return undefined;
|
|
126
|
+
detencion.avisados.add(threadId);
|
|
127
|
+
return textoDeDetencionParaHijo(detencion.texto);
|
|
128
|
+
},
|
|
129
|
+
/** La orden que NADIE llegó a leer —ni el raíz— sale como el turno siguiente, igual que una
|
|
130
|
+
* nota sobrante. Con texto vacío no queda nada que mandar. */
|
|
131
|
+
sobrante() {
|
|
132
|
+
if (detencion === undefined || detencion.raizAvisado || detencion.texto.trim() === "")
|
|
133
|
+
return undefined;
|
|
134
|
+
return detencion.texto;
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=detencion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detencion.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/detencion.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
|
|
19
19
|
import { razonamientoDe, razonamientoVisibleDe, textoDe } from "../../turno/puente.js";
|
|
20
|
+
/** Lo que llega al padre si, tras un corte, el resumen no dejó texto. */
|
|
21
|
+
const RELLENO_DEL_CORTE = "[Detenido a petición de la persona a mitad de una llamada, antes de poder resumir lo hecho.]";
|
|
20
22
|
/** El texto de un `content` de OpenAI, sea cadena o lista de partes. */
|
|
21
23
|
function textoDeContenido(contenido) {
|
|
22
24
|
if (typeof contenido === "string")
|
|
@@ -75,15 +77,41 @@ export function modeloParaTrueforge(opciones) {
|
|
|
75
77
|
const id = `xc-${++secuencia}`;
|
|
76
78
|
const creado = Math.floor(Date.now() / 1000);
|
|
77
79
|
const nombre = opciones.nombre ?? "xonecode";
|
|
80
|
+
let relleno = opciones.soloTexto?.();
|
|
81
|
+
const corte = relleno === undefined ? opciones.corte?.() : undefined;
|
|
82
|
+
const senalDelStream = corte === undefined ? senal : senal === undefined ? corte.senal : AbortSignal.any([senal, corte.senal]);
|
|
78
83
|
let acumulado;
|
|
79
|
-
|
|
84
|
+
/** Los trozos de UNA pasada: la normal y, si se corta, la del resumen. */
|
|
85
|
+
const pasada = async function* (lista, s) {
|
|
86
|
+
for await (const trozo of await modelo.stream(lista, s === undefined ? {} : { signal: s }))
|
|
87
|
+
yield trozo;
|
|
88
|
+
};
|
|
89
|
+
let trozos = pasada(mensajes, senalDelStream);
|
|
90
|
+
for (;;) {
|
|
91
|
+
let r;
|
|
92
|
+
try {
|
|
93
|
+
r = await trozos.next();
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
// Un aborto que es SOLO del corte —no del turno— no es un fallo: se pide el resumen.
|
|
97
|
+
if (corte === undefined || !corte.senal.aborted || senal?.aborted === true || relleno !== undefined)
|
|
98
|
+
throw e;
|
|
99
|
+
relleno = RELLENO_DEL_CORTE;
|
|
100
|
+
const dicho = acumulado === undefined ? "" : textoDe(acumulado);
|
|
101
|
+
acumulado = undefined;
|
|
102
|
+
trozos = pasada([...mensajes, ...(dicho.trim() === "" ? [] : [new AIMessage(dicho)]), new HumanMessage(corte.orden())], senal);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (r.done === true)
|
|
106
|
+
break;
|
|
107
|
+
const trozo = r.value;
|
|
80
108
|
acumulado = acumulado === undefined ? trozo : acumulado.concat(trozo);
|
|
81
109
|
const texto = textoDe(trozo);
|
|
82
110
|
// En los TROZOS va el razonamiento que se ENSEÑA, DeepSeek incluido: los trozos solo
|
|
83
111
|
// alimentan los eventos del chat. El mensaje que se guarda en el hilo es el `output` de
|
|
84
112
|
// abajo, que sigue con `razonamientoDe` — lo de DeepSeek no entra en la memoria.
|
|
85
113
|
const pensado = razonamientoVisibleDe(trozo);
|
|
86
|
-
const llamadas = (trozo.tool_call_chunks ?? []).map((t, i) => ({
|
|
114
|
+
const llamadas = (relleno === undefined ? (trozo.tool_call_chunks ?? []) : []).map((t, i) => ({
|
|
87
115
|
index: t.index ?? i,
|
|
88
116
|
...(t.id === undefined ? {} : { id: t.id, type: "function" }),
|
|
89
117
|
function: { ...(t.name === undefined ? {} : { name: t.name }), arguments: t.args ?? "" },
|
|
@@ -109,13 +137,17 @@ export function modeloParaTrueforge(opciones) {
|
|
|
109
137
|
],
|
|
110
138
|
};
|
|
111
139
|
}
|
|
112
|
-
const
|
|
140
|
+
const pedidas = acumulado?.tool_calls ?? [];
|
|
141
|
+
const llamadas = relleno === undefined ? pedidas : [];
|
|
142
|
+
if (relleno !== undefined && pedidas.length > 0)
|
|
143
|
+
opciones.alTirarLlamadas?.(pedidas.length);
|
|
113
144
|
const uso = acumulado?.usage_metadata;
|
|
114
145
|
const razonamiento = acumulado === undefined ? "" : razonamientoDe(acumulado);
|
|
146
|
+
const contenido = acumulado === undefined ? "" : textoDe(acumulado);
|
|
115
147
|
return {
|
|
116
148
|
output: {
|
|
117
149
|
role: "assistant",
|
|
118
|
-
content:
|
|
150
|
+
content: relleno !== undefined && contenido.trim() === "" ? relleno : contenido,
|
|
119
151
|
...(llamadas.length === 0
|
|
120
152
|
? {}
|
|
121
153
|
: {
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"modeloLangchain.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/modeloLangchain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function crearNota(texto) {
|
|
2
|
+
return { texto, vistaPorElRaiz: false };
|
|
3
|
+
}
|
|
4
|
+
/** Para el raíz: lo que la persona le dijo. */
|
|
5
|
+
export function textoDeNota(texto) {
|
|
6
|
+
return `[la persona escribió mientras trabajabas: «${texto}»]`;
|
|
7
|
+
}
|
|
8
|
+
/** Para un hijo: su interlocutor normal es quien le delegó, así que se dice que viene de fuera, y
|
|
9
|
+
* se le da la salida si no es de su encargo. */
|
|
10
|
+
export function textoDeNotaParaHijo(texto) {
|
|
11
|
+
return (`[la persona escribió mientras trabajabas: «${texto}». Si encaja en tu encargo, incorpóralo. ` +
|
|
12
|
+
"Si no, no lo hagas: termina tu respuesta con «PENDIENTE DE LA PERSONA: …» para que quien te delegó lo replanifique.]");
|
|
13
|
+
}
|
|
14
|
+
/** Para el raíz, cuando la nota ya se la quedó un hijo. */
|
|
15
|
+
export function textoDeNotaYaEntregada(texto, quien) {
|
|
16
|
+
return (`[la persona escribió mientras trabajabas: «${texto}». Se le pasó a ${quien} mientras trabajaba, y su respuesta está arriba: ` +
|
|
17
|
+
"NO la vuelvas a encargar. Actúa solo sobre lo que diga como PENDIENTE DE LA PERSONA o no cubierto.]");
|
|
18
|
+
}
|
|
19
|
+
/** Los textos que se le meten a ESE hilo antes de su llamada, marcando lo entregado. */
|
|
20
|
+
export function entregarNotas(notas, threadId, ctx) {
|
|
21
|
+
const textos = [];
|
|
22
|
+
for (const n of notas) {
|
|
23
|
+
if (threadId === ctx.hiloRaiz) {
|
|
24
|
+
if (n.vistaPorElRaiz)
|
|
25
|
+
continue;
|
|
26
|
+
n.vistaPorElRaiz = true;
|
|
27
|
+
if (n.duenio === undefined) {
|
|
28
|
+
n.duenio = threadId;
|
|
29
|
+
textos.push(textoDeNota(n.texto));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
textos.push(textoDeNotaYaEntregada(n.texto, ctx.nombreDe(n.duenio)));
|
|
33
|
+
}
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (n.duenio !== undefined || n.vistaPorElRaiz || ctx.hijosVivos !== 1)
|
|
37
|
+
continue;
|
|
38
|
+
n.duenio = threadId;
|
|
39
|
+
textos.push(textoDeNotaParaHijo(n.texto));
|
|
40
|
+
}
|
|
41
|
+
return textos;
|
|
42
|
+
}
|
|
43
|
+
/** Lo que NADIE se quedó, para mandarlo como el turno siguiente. `undefined` si no queda ninguna —
|
|
44
|
+
* así el llamador no confunde "sin sobrantes" con una cadena vacía. */
|
|
45
|
+
export function sobrantes(notas) {
|
|
46
|
+
const sinEntregar = notas.filter((n) => n.duenio === undefined).map((n) => n.texto);
|
|
47
|
+
return sinEntregar.length === 0 ? undefined : sinEntregar.join("\n\n");
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=notas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notas.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/notas.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;AAC1C,CAAC;AAWD,+CAA+C;AAC/C,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,8CAA8C,KAAK,IAAI,CAAC;AACjE,CAAC;AAED;iDACiD;AACjD,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,OAAO,CACL,8CAA8C,KAAK,2CAA2C;QAC9F,sHAAsH,CACvH,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,sBAAsB,CAAC,KAAa,EAAE,KAAa;IACjE,OAAO,CACL,8CAA8C,KAAK,mBAAmB,KAAK,mDAAmD;QAC9H,qGAAqG,CACtG,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,KAAsB,EAAE,QAAgB,EAAE,GAAsB;IAC5F,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,QAAQ,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,cAAc;gBAAE,SAAS;YAC/B,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC3B,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvE,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC,UAAU,KAAK,CAAC;YAAE,SAAS;QACjF,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;wEACwE;AACxE,MAAM,UAAU,SAAS,CAAC,KAAsB;IAC9C,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpF,OAAO,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -51,16 +51,22 @@ import { modeloParaTrueforge } from "./modeloLangchain.js";
|
|
|
51
51
|
import { TOOLS_DE_LECTURA } from "./toolsDeFichero.js";
|
|
52
52
|
import { topeAgotadoDe, traducirEvento } from "./eventosTrueforge.js";
|
|
53
53
|
import { anuncioDeSkills } from "./skillsTrueforge.js";
|
|
54
|
-
import { capabilitiesDe, capacidadDeFecha, capacidadDeFicheros, capacidadDeInstrucciones, capacidadDePropias, capacidadDeRecortes, capacidadesDelEspecialista, clasesDeTools, toolsDe, } from "./capacidades.js";
|
|
54
|
+
import { capabilitiesDe, capacidadDeFecha, capacidadDeFicheros, capacidadDeInstrucciones, capacidadDeNotas, capacidadDePropias, capacidadDeRecortes, capacidadesDelEspecialista, clasesDeTools, toolsDe, } from "./capacidades.js";
|
|
55
55
|
import { crearDiagnosticoDeTools } from "../../turno/diagnosticoDeTools.js";
|
|
56
|
+
import { encenderTrazaDeErrores } from "../../trazaDeErroresEnDisco.js";
|
|
57
|
+
import { anotarPaso } from "../../../core/trazaDeErrores.js";
|
|
58
|
+
import { entornoConDepuracion } from "../../turno/depuracion.js";
|
|
56
59
|
import { detalleDe, parametrosDe } from "../../turno/resumenDeTool.js";
|
|
57
60
|
import { apartarMemoria, cargarMemoria, fotoSaneada, guardarMemoria, textoDeMemoriaDescartada } from "./memoriaTrueforge.js";
|
|
61
|
+
import { crearNota, sobrantes } from "./notas.js";
|
|
62
|
+
import { crearControlDeDetencion, RESUMEN_DE_RELLENO } from "./detencion.js";
|
|
58
63
|
import { crearNavegacionXone } from "../../grafo/navegacionXone.js";
|
|
59
64
|
import { hechosDelProyectoDe } from "../../navegacion/hechosEnDisco.js";
|
|
60
65
|
import { conHechosDelProyecto } from "../../../core/hechosDelProyecto.js";
|
|
61
66
|
import { crearBusquedaRegex } from "../../grafo/busquedaRegex.js";
|
|
62
67
|
import { crearCopiarArtefacto } from "../../grafo/copiarArtefacto.js";
|
|
63
68
|
import { crearUnirSecciones } from "../../grafo/unirSecciones.js";
|
|
69
|
+
import { crearIncorporarAdjunto, recibeIncorporarAdjunto } from "../../grafo/incorporarAdjunto.js";
|
|
64
70
|
import { crearCriticaVisual } from "../../grafo/criticaVisual.js";
|
|
65
71
|
import { crearTraerDeLaMaquina } from "../../grafo/traerDeLaMaquina.js";
|
|
66
72
|
import { invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
|
|
@@ -151,6 +157,13 @@ function preguntaDeLaFoto(foto) {
|
|
|
151
157
|
};
|
|
152
158
|
}
|
|
153
159
|
const claveDe = (hilo, id) => `${hilo}:${id}`;
|
|
160
|
+
/**
|
|
161
|
+
* `agregarNota` no vive todavía en `SesionReal` (IXCODE-4, Task 6 se la añade ahí como opcional,
|
|
162
|
+
* compartida con deepagents): se ensancha el tipo de retorno AQUÍ, en vez de esperar a esa task,
|
|
163
|
+
* porque una sesión sin ella tipado como `SesionReal` a secas dejaría `s.agregarNota(...)` en
|
|
164
|
+
* rojo bajo `tsc --noEmit` desde este mismo commit. Sigue siendo un `SesionReal` válido en
|
|
165
|
+
* cualquier sitio que lo espere (`turnoReal.ts#abrirSesionReal`), por ser una intersección.
|
|
166
|
+
*/
|
|
154
167
|
export async function abrirSesionTrueforge(opciones) {
|
|
155
168
|
const { raiz } = opciones;
|
|
156
169
|
let modelos = opciones.modelos;
|
|
@@ -160,7 +173,14 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
160
173
|
* formato, así que `xonecode traza` compara los dos motores. La omisión es la real —entrar por
|
|
161
174
|
* parámetro solo sirve para doblarla—, que es lo que evita dejarla escrita y sin montar.
|
|
162
175
|
*/
|
|
163
|
-
const
|
|
176
|
+
const entornoDeDiagnostico = entornoConDepuracion(opciones.depurar === true);
|
|
177
|
+
const diagnostico = opciones.diagnostico ?? crearDiagnosticoDeTools(raiz, entornoDeDiagnostico);
|
|
178
|
+
/**
|
|
179
|
+
* La traza de EXCEPCIONES e HITOS, la MISMA de deepagents (`turnoReal.ts`) y que aquí
|
|
180
|
+
* faltaba por completo: TrueForge nunca la encendía, ni siquiera con la variable de entorno
|
|
181
|
+
* puesta a mano.
|
|
182
|
+
*/
|
|
183
|
+
encenderTrazaDeErrores(raiz, entornoDeDiagnostico);
|
|
164
184
|
const tracker = createTokenTracker();
|
|
165
185
|
const oyentes = new Set();
|
|
166
186
|
let aborto;
|
|
@@ -191,12 +211,30 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
191
211
|
if (a.mime !== undefined && a.mime.startsWith("image/"))
|
|
192
212
|
capturasDelTurno.push(a);
|
|
193
213
|
};
|
|
214
|
+
/** Lo que la persona escribió mientras el agente trabajaba, IXCODE-4: se entrega por
|
|
215
|
+
* `capacidadDeNotas`, la MISMA instancia en la raíz y en cada hijo. */
|
|
216
|
+
const notas = [];
|
|
217
|
+
/** DETENER y replanificar (`detencion.ts`): viaja por el mismo procesador que las notas. */
|
|
218
|
+
const detencion = crearControlDeDetencion(HILO_RAIZ);
|
|
219
|
+
/** Tool calls tiradas por DETENER en la sesión: si se queda en cero, el filtro es solo red. */
|
|
220
|
+
let llamadasTiradasPorDetener = 0;
|
|
221
|
+
const capacidadDeNotasDeLaSesion = capacidadDeNotas(notas, {
|
|
222
|
+
detencion,
|
|
223
|
+
nombreDe: (h) => quienEs.get(h) ?? h,
|
|
224
|
+
hiloRaiz: HILO_RAIZ,
|
|
225
|
+
});
|
|
226
|
+
/** Lo que la persona escribió en el turno y nadie leyó: notas y la orden de DETENER. */
|
|
227
|
+
const sinLeerDelTurno = () => {
|
|
228
|
+
const sinLeer = [sobrantes(notas), detencion.sobrante()].filter((t) => t !== undefined);
|
|
229
|
+
return sinLeer.length === 0 ? undefined : sinLeer.join("\n\n");
|
|
230
|
+
};
|
|
194
231
|
const montarBackend = (ejecucion) => backendDeAgente({
|
|
195
232
|
raiz,
|
|
196
233
|
ficheros: ficherosDelProyecto(raiz),
|
|
197
234
|
...(opciones.artefactos === undefined
|
|
198
235
|
? {}
|
|
199
236
|
: { artefactos: { carpeta: opciones.artefactos, alEscribir: anotarArtefacto } }),
|
|
237
|
+
...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
|
|
200
238
|
...(ejecucion === undefined ? {} : { ejecucion }),
|
|
201
239
|
});
|
|
202
240
|
const backend = montarBackend();
|
|
@@ -283,6 +321,12 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
283
321
|
: []),
|
|
284
322
|
// El mismo reparto que deepagents (`xoneAgent.ts`): a quien declara `escribeEn`.
|
|
285
323
|
...((agente.escribeEn ?? []).length > 0 ? [crearUnirSecciones({ raiz, perfil: agente })] : []),
|
|
324
|
+
// Meter un adjunto del chat en el proyecto, con el reparto de deepagents: a quien escribe el
|
|
325
|
+
// proyecto entero y solo con la carpeta montada. Pide aprobación: `capacidadesDelEspecialista`
|
|
326
|
+
// la pone en `requireApprovalForTools`, y `rondasDe` la pregunta con su tarjeta (`cambioDe`).
|
|
327
|
+
...(opciones.adjuntos !== undefined && recibeIncorporarAdjunto(agente)
|
|
328
|
+
? [crearIncorporarAdjunto({ raiz, carpetaDeAdjuntos: opciones.adjuntos, perfil: agente })]
|
|
329
|
+
: []),
|
|
286
330
|
];
|
|
287
331
|
/**
|
|
288
332
|
* **Un cliente de modelo por papel, modelo y esfuerzo, que dura la SESIÓN** —hasta `/modelo`—, y
|
|
@@ -354,6 +398,7 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
354
398
|
*/
|
|
355
399
|
const crearHijo = async (params) => {
|
|
356
400
|
const agente = especialistas().find((a) => a.nombre === params.request.name);
|
|
401
|
+
detencion.nacio(params.threadId);
|
|
357
402
|
quienEs.set(params.threadId, agente?.nombre ?? params.request.name);
|
|
358
403
|
if (agente !== undefined)
|
|
359
404
|
especialistaDeHilo.set(params.threadId, agente.nombre);
|
|
@@ -364,7 +409,14 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
364
409
|
const piezas = capacidadesDelEspecialista(agente, params.request.name, {
|
|
365
410
|
backend: backend,
|
|
366
411
|
propias: propiasDe,
|
|
367
|
-
|
|
412
|
+
notas: capacidadDeNotasDeLaSesion,
|
|
413
|
+
conShell: () => montarBackend({
|
|
414
|
+
entorno: entornoDeLaShellDelProyecto(raiz, opciones.artefactos),
|
|
415
|
+
// El MISMO patrón que ya usa `modeloParaTrueforge` un poco más arriba en este
|
|
416
|
+
// fichero: un getter que se reevalúa en cada llamada, así siempre lee el
|
|
417
|
+
// `AbortController` de la RONDA en curso y no uno capturado al construir.
|
|
418
|
+
senal: () => aborto?.signal,
|
|
419
|
+
}),
|
|
368
420
|
});
|
|
369
421
|
const nombres = toolsDe(piezas);
|
|
370
422
|
const nota = notaDeTools(nombres, agente === undefined ? LIMITE_DEL_GENERICO : LIMITES_DE[clase]);
|
|
@@ -381,6 +433,13 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
381
433
|
? clienteDe(`papel:${papel}:${agente?.esfuerzo ?? ""}`, () => modelos.paraPapel(papel, agente?.esfuerzo))
|
|
382
434
|
: clienteDe(`modelo:${agente.modelo}:${agente.esfuerzo ?? ""}`, () => modelos.paraModelo(agente.modelo, agente.esfuerzo)),
|
|
383
435
|
senal: () => aborto?.signal,
|
|
436
|
+
soloTexto: () => (detencion.soloTexto(params.threadId) ? RESUMEN_DE_RELLENO : undefined),
|
|
437
|
+
corte: () => detencion.corte(params.threadId),
|
|
438
|
+
alTirarLlamadas: (n) => {
|
|
439
|
+
llamadasTiradasPorDetener += n;
|
|
440
|
+
// A la traza de hitos (con «Depurar»): es la medida de si el filtro hace falta o es red.
|
|
441
|
+
anotarPaso("trueforge.detener", `${quienEs.get(params.threadId) ?? params.threadId}: ${n} tool call(s) tiradas`)();
|
|
442
|
+
},
|
|
384
443
|
}),
|
|
385
444
|
messages: [{ role: "user", content: params.request.input }],
|
|
386
445
|
// Los topes MEDIDOS de deepagents: el conductor más, porque cada paso suyo es un comando.
|
|
@@ -440,6 +499,7 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
440
499
|
capacidadDePropias(propiasDelRaiz, backend),
|
|
441
500
|
capacidadDeRecortes(backend),
|
|
442
501
|
capacidadDeFecha(),
|
|
502
|
+
capacidadDeNotasDeLaSesion,
|
|
443
503
|
]),
|
|
444
504
|
/**
|
|
445
505
|
* **La conversación se RESUME al mismo umbral que deepagents** (`UMBRAL_RESUMEN_TOKENS`):
|
|
@@ -604,6 +664,7 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
604
664
|
throw new Error("la sesión está cerrada");
|
|
605
665
|
const t0 = Date.now();
|
|
606
666
|
cancelado = false;
|
|
667
|
+
detencion.reiniciar();
|
|
607
668
|
const instantanea = await tomarInstantanea(raiz, opciones.entorno.git);
|
|
608
669
|
const tope = opciones.topeDeRondas ?? MAX_APPROVAL_ROUNDS;
|
|
609
670
|
const aplicadasSinPreguntar = [];
|
|
@@ -924,6 +985,13 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
924
985
|
// deepagents — un aviso que salta cuando no ha pasado nada enseña a ignorarlo.
|
|
925
986
|
avisos: (b) => [
|
|
926
987
|
...(memoriaDescartada === undefined ? [] : [memoriaDescartada]),
|
|
988
|
+
...(sinLeerDelTurno() === undefined
|
|
989
|
+
? []
|
|
990
|
+
: cancelado
|
|
991
|
+
? // PARAR es «para»: lo escrito que nadie leyó no arranca otro turno —medido, lo
|
|
992
|
+
// hacía—, pero tampoco se pierde en silencio: se dice, con su texto, para copiarlo.
|
|
993
|
+
[`⏹ turno parado: no se manda lo que escribiste mientras trabajaba — «${sinLeerDelTurno()}»`]
|
|
994
|
+
: [`⚠ una nota no se pudo entregar a tiempo: se manda como el turno siguiente`]),
|
|
927
995
|
...(b.corrio("verify") || !escribioProyecto
|
|
928
996
|
? []
|
|
929
997
|
: [`⚠ el verificador no ha corrido en este turno${motivoSinVerificar === undefined ? "" : ` (${motivoSinVerificar})`}`]),
|
|
@@ -1003,6 +1071,13 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
1003
1071
|
}
|
|
1004
1072
|
}
|
|
1005
1073
|
const cambios = await instantanea.cambios();
|
|
1074
|
+
// Calculado y VACIADO aquí, DESPUÉS del único `await` que queda entre el `finally` y el
|
|
1075
|
+
// `return`: hacerlo antes (como sugería el borrador) deja una ventana en la que una nota
|
|
1076
|
+
// empujada durante ese `await` cae en una cola ya vacía y sobrevive muda al turno
|
|
1077
|
+
// siguiente — justo lo que este campo existe para impedir.
|
|
1078
|
+
const notasSobrantes = cancelado ? undefined : sinLeerDelTurno();
|
|
1079
|
+
detencion.reiniciar();
|
|
1080
|
+
notas.length = 0; // Se sirvieron o se reportan aquí: no siguen vivas para el próximo turno.
|
|
1006
1081
|
return {
|
|
1007
1082
|
bitacora,
|
|
1008
1083
|
cambios,
|
|
@@ -1012,6 +1087,7 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
1012
1087
|
...(hallazgosDelTurno.length === 0 ? {} : { hallazgos: hallazgosDelTurno }),
|
|
1013
1088
|
...(preexistentesDelTurno === undefined ? {} : { preexistentes: preexistentesDelTurno }),
|
|
1014
1089
|
...(motivoSinVerificar === undefined ? {} : { motivoSinVerificar }),
|
|
1090
|
+
...(notasSobrantes === undefined ? {} : { notasSobrantes }),
|
|
1015
1091
|
};
|
|
1016
1092
|
},
|
|
1017
1093
|
async cambiarModelos(nuevos) {
|
|
@@ -1042,6 +1118,27 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
1042
1118
|
cancelado = true;
|
|
1043
1119
|
aborto?.abort(new Error("turno cancelado por el usuario"));
|
|
1044
1120
|
},
|
|
1121
|
+
/**
|
|
1122
|
+
* Empuja la nota a la cola de la sesión, sin más: no comprueba que haya un turno en marcha
|
|
1123
|
+
* —ese contrato lo sostiene quien llama (`web/servidor/vestibulo.ts`, Task 6)—, así que
|
|
1124
|
+
* llamarlo sin turno en curso no lanza, y la nota queda ahí para la próxima llamada al
|
|
1125
|
+
* modelo que la recoja `capacidadDeNotasDeLaSesion`.
|
|
1126
|
+
*/
|
|
1127
|
+
agregarNota(texto) {
|
|
1128
|
+
notas.push(crearNota(texto));
|
|
1129
|
+
},
|
|
1130
|
+
/**
|
|
1131
|
+
* DETENER y replanificar (`detencion.ts`): los especialistas en marcha cierran con su resumen
|
|
1132
|
+
* en su siguiente llamada, y el raíz replanifica con ellos y con `texto`. Solo vale DENTRO de
|
|
1133
|
+
* un turno —el siguiente empieza de cero—, y por eso el servidor solo la manda con uno en vuelo;
|
|
1134
|
+
* si el turno cierra sin que nadie la lea, su texto sale como sobrante.
|
|
1135
|
+
*/
|
|
1136
|
+
detener(texto) {
|
|
1137
|
+
detencion.detener(texto);
|
|
1138
|
+
},
|
|
1139
|
+
get llamadasTiradasPorDetener() {
|
|
1140
|
+
return llamadasTiradasPorDetener;
|
|
1141
|
+
},
|
|
1045
1142
|
consumo() {
|
|
1046
1143
|
return {
|
|
1047
1144
|
modelo: { entrada: tracker.input, salida: tracker.output, cache: tracker.cache },
|