chocolatito-code 1.6.11 → 1.6.12

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.
@@ -56,3 +56,27 @@ export declare function liberarHuecos(): void;
56
56
  * que hacer nada: es lo unico que se arregla solo con esperar.
57
57
  */
58
58
  export declare function mensajeDeEspera(segundos: number): string;
59
+ /**
60
+ * Espera a que se libere el hueco, en vez de devolverle la pared al usuario.
61
+ *
62
+ * DE DONDE SALE
63
+ *
64
+ * La misma sesion, un paso mas alla. Ya no se gastaba una peticion por intento
65
+ * -eso lo arreglo lo de arriba-, pero el usuario seguia atrapado:
66
+ *
67
+ * > sigue
68
+ * ⏸ Faltan 144s.
69
+ * > sigoe
70
+ * ⏸ Faltan 133s.
71
+ *
72
+ * Tecleando contra una pared que el programa sabia medir. Si sabemos que faltan
73
+ * 133 segundos, esperarlos es trabajo del programa, no del que paga. Se avisa,
74
+ * se cuenta hacia atras y se sigue solo; con Esc se deja.
75
+ *
76
+ * Vuelve `true` si ya hay hueco y `false` si el usuario corto.
77
+ */
78
+ export declare function esperarAlHueco(opciones: {
79
+ signal?: AbortSignal;
80
+ alPasarUnSegundo?: (quedan: number) => void;
81
+ dormir?: (ms: number) => Promise<void>;
82
+ }): Promise<boolean>;
@@ -79,3 +79,37 @@ export function mensajeDeEspera(segundos) {
79
79
  "No llamo al motor porque la respuesta seria la misma y cada intento puede alargar la espera. " +
80
80
  "No hace falta que hagas nada: el hueco se libera solo.");
81
81
  }
82
+ /**
83
+ * Espera a que se libere el hueco, en vez de devolverle la pared al usuario.
84
+ *
85
+ * DE DONDE SALE
86
+ *
87
+ * La misma sesion, un paso mas alla. Ya no se gastaba una peticion por intento
88
+ * -eso lo arreglo lo de arriba-, pero el usuario seguia atrapado:
89
+ *
90
+ * > sigue
91
+ * ⏸ Faltan 144s.
92
+ * > sigoe
93
+ * ⏸ Faltan 133s.
94
+ *
95
+ * Tecleando contra una pared que el programa sabia medir. Si sabemos que faltan
96
+ * 133 segundos, esperarlos es trabajo del programa, no del que paga. Se avisa,
97
+ * se cuenta hacia atras y se sigue solo; con Esc se deja.
98
+ *
99
+ * Vuelve `true` si ya hay hueco y `false` si el usuario corto.
100
+ */
101
+ export async function esperarAlHueco(opciones) {
102
+ const { signal, alPasarUnSegundo } = opciones;
103
+ const dormir = opciones.dormir || ((ms) => new Promise((r) => setTimeout(r, ms)));
104
+ // Se relee en cada vuelta en vez de contar desde un numero fijo: si algo
105
+ // libera los huecos antes -otra respuesta del motor-, se sale en el acto.
106
+ let quedan = segundosDeEspera();
107
+ while (quedan > 0) {
108
+ if (signal?.aborted)
109
+ return false;
110
+ alPasarUnSegundo?.(quedan);
111
+ await dormir(1000);
112
+ quedan = segundosDeEspera();
113
+ }
114
+ return !signal?.aborted;
115
+ }
@@ -8,7 +8,7 @@ import { CONTEXT_WINDOW, MAX_OUTPUT_TOKENS, COMPACT_THRESHOLD_TOKENS, } from "..
8
8
  import { withRetry, isContextOverflow, esDemasiadasEnCurso } from "./retry.js";
9
9
  import { canRunInParallel } from "../tools/safety.js";
10
10
  import { createEngineClient, explicarErrorDelMotor, motivoDeParadaDelError, } from "../config/engine.js";
11
- import { anotarHuecosOcupados, liberarHuecos, mensajeDeEspera, segundosDeEspera } from "./huecos.js";
11
+ import { anotarHuecosOcupados, esperarAlHueco, liberarHuecos, mensajeDeEspera, segundosDeEspera, } from "./huecos.js";
12
12
  import { MarkdownStream } from "../ui/markdownStream.js";
13
13
  import { checkQuota, recordUsage, mensajeDeCorte, quotaBadge } from "../config/quota.js";
14
14
  import { ReasoningStream } from "../ui/reasoningStream.js";
@@ -461,9 +461,43 @@ export class AgentLoop {
461
461
  // llamada es justo la que puede refrescar la reserva y alargar la espera.
462
462
  const espera = segundosDeEspera();
463
463
  if (espera > 0) {
464
+ // ESPERAR ES TRABAJO DEL PROGRAMA, NO DEL QUE PAGA
465
+ //
466
+ // Antes esto devolvia el aviso y cortaba el turno. El usuario escribia
467
+ // "sigue", se llevaba "faltan 144s", escribia otra vez y se llevaba
468
+ // "faltan 133s": tecleando contra una pared que el programa sabia medir.
469
+ // Si sabemos cuanto falta, se espera y se sigue solo. Con Esc se deja.
464
470
  const aviso = mensajeDeEspera(espera);
465
- salida.linea(chalk.yellow(`\n⏸ ${aviso}\n`));
466
- return parada("ocupado", aviso);
471
+ // SOLO SE ESPERA SI HAY ALGUIEN DELANTE.
472
+ //
473
+ // Esperar tres minutos es una pausa cuando se ve la cuenta atras y se
474
+ // puede cortar con Esc. Sin terminal -CI, `chocolatito "haz X"`, una
475
+ // tuberia- es un cuelgue mudo de tres minutos que nadie puede parar, y
476
+ // ademas ahi no hay nadie a quien ahorrarle el teclear. Se dice y se
477
+ // corta, como antes.
478
+ if (!process.stdin.isTTY) {
479
+ salida.linea(chalk.yellow(`\n⏸ ${aviso}\n`));
480
+ return parada("ocupado", aviso);
481
+ }
482
+ salida.linea(chalk.yellow(`\n⏸ ${aviso}`));
483
+ salida.linea(chalk.gray(" Espero y sigo solo cuando se libere. Esc para dejarlo.\n"));
484
+ const vigilante = new InterruptWatcher();
485
+ const senal = vigilante.start();
486
+ const spinnerEspera = new DynamicSpinner();
487
+ spinnerEspera.start();
488
+ const hayHueco = await esperarAlHueco({
489
+ signal: senal,
490
+ alPasarUnSegundo: (quedan) => {
491
+ spinnerEspera.setPrefijo(`Esperando hueco de la licencia (quedan ${quedan}s)`);
492
+ },
493
+ });
494
+ spinnerEspera.stop();
495
+ vigilante.stop();
496
+ if (!hayHueco) {
497
+ salida.linea(chalk.yellow("\n⏸ Interrumpido. Dime como seguir."));
498
+ return parada("interrumpido");
499
+ }
500
+ salida.linea(chalk.green(" ✔ Hueco libre. Sigo.\n"));
467
501
  }
468
502
  // Cuota ANTES de gastar. Si no queda margen, se dice y no se llama al motor:
469
503
  // avisar despues de haber gastado no sirve de nada.
@@ -742,6 +776,18 @@ export class AgentLoop {
742
776
  // porque la conexion estaba bien.
743
777
  if (!llegoElFinal) {
744
778
  watcher.stop();
779
+ // SE CIERRA LA PETICION MUERTA, Y ESTO NO ES LIMPIEZA: ES EL HUECO.
780
+ //
781
+ // El cuerpo se corto, pero por lo que respecta al proxy la peticion
782
+ // sigue en curso y sigue ocupando uno de los cuatro huecos de la
783
+ // licencia hasta que ALGO la cierre. Por eso el mensaje del proxy dice
784
+ // "si acabas de interrumpir una, el hueco se libera solo en 206s": son
785
+ // tres minutos y medio de servicio perdido por una conexion que ya
786
+ // estaba muerta de este lado. Abortando aqui se suelta en el momento.
787
+ try {
788
+ stream?.controller?.abort();
789
+ }
790
+ catch { }
745
791
  // Lo que llego se guarda, pero MARCADO. Sin la marca, en el turno
746
792
  // siguiente el modelo lee su propia frase a medias como algo que decidio
747
793
  // dejar asi, y responde a un texto que nadie escribio.
@@ -7,6 +7,12 @@ export declare class DynamicSpinner {
7
7
  private prefix;
8
8
  tokenCount: number;
9
9
  constructor(prefix?: string);
10
+ /**
11
+ * Cambia el texto mientras gira. Hace falta para las esperas con cuenta
12
+ * atras: el prefijo se fijaba al arrancar y el numero de segundos que faltan
13
+ * cambia cada vuelta.
14
+ */
15
+ setPrefijo(prefijo: string): void;
10
16
  start(initialPrefix?: string): void;
11
17
  private tick;
12
18
  /**
@@ -42,6 +42,14 @@ export class DynamicSpinner {
42
42
  constructor(prefix = "") {
43
43
  this.prefix = prefix;
44
44
  }
45
+ /**
46
+ * Cambia el texto mientras gira. Hace falta para las esperas con cuenta
47
+ * atras: el prefijo se fijaba al arrancar y el numero de segundos que faltan
48
+ * cambia cada vuelta.
49
+ */
50
+ setPrefijo(prefijo) {
51
+ this.prefix = prefijo;
52
+ }
45
53
  start(initialPrefix) {
46
54
  if (this.isRunning)
47
55
  return;
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "minimum_chrome_version": "102",
4
4
  "name": "Chocolatito Code",
5
- "version": "1.6.11",
5
+ "version": "1.6.12",
6
6
  "description": "Deja que Chocolatito Code trabaje dentro de tu Chrome, en segundo plano y con tus sesiones ya iniciadas.",
7
7
  "permissions": [
8
8
  "tabs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chocolatito-code",
3
- "version": "1.6.11",
3
+ "version": "1.6.12",
4
4
  "description": "Agente autónomo de programación para la terminal, con control real del ordenador y del navegador. Desarrollado por Chocolatito.",
5
5
  "type": "module",
6
6
  "bin": {