ghostykit 0.3.2 → 0.4.1
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/README.md +44 -57
- package/dist/chunks/chunk-JQEB37IY.js +479 -0
- package/dist/chunks/chunk-TMEHQZWL.js +89 -0
- package/dist/core/index.d.ts +2 -3
- package/dist/core/index.js +13 -23
- package/dist/core/reducer.d.ts +27 -45
- package/dist/core/steps.d.ts +9 -1
- package/dist/core/types.d.ts +42 -159
- package/dist/react/Bubble.d.ts +2 -6
- package/dist/react/Composer.d.ts +6 -1
- package/dist/react/ConfirmCard.d.ts +3 -4
- package/dist/react/Piloto.d.ts +3 -10
- package/dist/react/Status.d.ts +1 -13
- package/dist/react/index.d.ts +6 -6
- package/dist/react/index.js +219 -409
- package/dist/react/strings.d.ts +2 -18
- package/dist/react/usePilot.d.ts +31 -43
- package/dist/styles.css +2 -103
- package/dist/transport/index.d.ts +40 -30
- package/dist/transport/index.js +3 -13
- package/package.json +16 -9
- package/dist/chunks/chunk-O6FCE4CS.js +0 -670
- package/dist/chunks/chunk-XZHX2NZT.js +0 -375
- package/dist/core/reconcile.d.ts +0 -7
- package/dist/react/connectingGate.d.ts +0 -17
- package/dist/transport/postStream.d.ts +0 -44
- package/dist/transport/types.d.ts +0 -47
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// src/transport/index.ts
|
|
2
|
+
var PilotHttpError = class extends Error {
|
|
3
|
+
constructor(message, status, code, retryAfter) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "PilotHttpError";
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.retryAfter = retryAfter;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
async function readSse(body, onMessage) {
|
|
12
|
+
const reader = body.getReader();
|
|
13
|
+
const decoder = new TextDecoder();
|
|
14
|
+
let buffer = "";
|
|
15
|
+
let event = "message";
|
|
16
|
+
let data = [];
|
|
17
|
+
const flush = () => {
|
|
18
|
+
if (data.length) onMessage({ event, data: data.join("\n") });
|
|
19
|
+
event = "message";
|
|
20
|
+
data = [];
|
|
21
|
+
};
|
|
22
|
+
for (; ; ) {
|
|
23
|
+
const { value, done } = await reader.read();
|
|
24
|
+
if (done) break;
|
|
25
|
+
buffer += decoder.decode(value, { stream: true });
|
|
26
|
+
let nl;
|
|
27
|
+
while ((nl = buffer.search(/\r\n|\r|\n/)) >= 0) {
|
|
28
|
+
const line = buffer.slice(0, nl);
|
|
29
|
+
buffer = buffer.slice(nl + (buffer[nl] === "\r" && buffer[nl + 1] === "\n" ? 2 : 1));
|
|
30
|
+
if (line === "") flush();
|
|
31
|
+
else if (line.startsWith(":")) continue;
|
|
32
|
+
else {
|
|
33
|
+
const i = line.indexOf(":");
|
|
34
|
+
const field = i < 0 ? line : line.slice(0, i);
|
|
35
|
+
const val = i < 0 ? "" : line.slice(i + 1).replace(/^ /, "");
|
|
36
|
+
if (field === "event") event = val;
|
|
37
|
+
else if (field === "data") data.push(val);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
flush();
|
|
42
|
+
}
|
|
43
|
+
function createAgUiTransport(opts) {
|
|
44
|
+
const doFetch = (...a) => (opts.fetch ?? fetch)(...a);
|
|
45
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
46
|
+
const retries = opts.retries ?? 6;
|
|
47
|
+
return {
|
|
48
|
+
async run(input, onEvent, signal) {
|
|
49
|
+
const body = JSON.stringify(input);
|
|
50
|
+
for (let attempt = 0; ; attempt++) {
|
|
51
|
+
const res = await doFetch(opts.url, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
credentials: opts.credentials ?? "same-origin",
|
|
54
|
+
headers: { "content-type": "application/json", accept: "text/event-stream", ...opts.headers },
|
|
55
|
+
body,
|
|
56
|
+
signal
|
|
57
|
+
});
|
|
58
|
+
const retryAfter = Number(res.headers.get("Retry-After")) || void 0;
|
|
59
|
+
if (res.status === 503 && attempt < retries) {
|
|
60
|
+
await sleep((retryAfter ?? 3) * 1e3);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (!res.ok) {
|
|
64
|
+
const json = await res.json().catch(() => null);
|
|
65
|
+
throw new PilotHttpError(json?.message ?? json?.error ?? `Error ${res.status}`, res.status, json?.error, retryAfter);
|
|
66
|
+
}
|
|
67
|
+
if (!res.body) return;
|
|
68
|
+
const serverDate = Date.parse(res.headers.get("date") ?? "");
|
|
69
|
+
const skew = Number.isNaN(serverDate) ? null : serverDate - Date.now();
|
|
70
|
+
await readSse(res.body, ({ data }) => {
|
|
71
|
+
if (!data) return;
|
|
72
|
+
try {
|
|
73
|
+
const event = JSON.parse(data);
|
|
74
|
+
if (skew !== null && typeof event.timestamp !== "number") event.timestamp = Date.now() + skew;
|
|
75
|
+
onEvent(event);
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
PilotHttpError,
|
|
87
|
+
readSse,
|
|
88
|
+
createAgUiTransport
|
|
89
|
+
};
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from "./types";
|
|
2
|
-
export {
|
|
3
|
-
export { reconcileTurns } from "./reconcile";
|
|
2
|
+
export { argsDetail, beginSend, createPilotState, dropLastExchange, expiryMs, lastUserTurn, messagesToTurns, reduceAgUiEvent, resolvePermission, sendFailed, stopTurn, toPermission, } from "./reducer";
|
|
4
3
|
export { isNarration, narrationToMarkdown, splitNarration } from "./narration";
|
|
5
4
|
export { cleanReplyOption, extractReplyOptions, type ReplyOptions } from "./options";
|
|
6
|
-
export { TOOL_VERBS_EN, TOOL_VERBS_ES, groupSteps, isRunning, stepLabel, summarizeTools, toolName, type ToolVerb, type ToolVerbs, } from "./steps";
|
|
5
|
+
export { TOOL_VERBS_EN, TOOL_VERBS_ES, groupSteps, isRunning, stepLabel, summarizeTools, toolName, toolNames, type ToolVerb, type ToolVerbs, } from "./steps";
|
|
7
6
|
export { applyReferences, cleanUserText, formatDuration, systemNoteOf } from "./text";
|
package/dist/core/index.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
RESTART_NOTICE,
|
|
3
|
-
RESUME_TEXT,
|
|
4
2
|
TOOL_VERBS_EN,
|
|
5
3
|
TOOL_VERBS_ES,
|
|
6
|
-
|
|
7
|
-
applyHistory,
|
|
4
|
+
argsDetail,
|
|
8
5
|
beginSend,
|
|
9
6
|
cleanReplyOption,
|
|
10
7
|
createPilotState,
|
|
@@ -15,21 +12,19 @@ import {
|
|
|
15
12
|
isNarration,
|
|
16
13
|
isRunning,
|
|
17
14
|
lastUserTurn,
|
|
15
|
+
messagesToTurns,
|
|
18
16
|
narrationToMarkdown,
|
|
19
|
-
|
|
20
|
-
reconcileWith,
|
|
21
|
-
reducePilotEvent,
|
|
17
|
+
reduceAgUiEvent,
|
|
22
18
|
resolvePermission,
|
|
23
|
-
resumeMode,
|
|
24
|
-
sendAccepted,
|
|
25
19
|
sendFailed,
|
|
26
|
-
sendRejectedBusy,
|
|
27
20
|
splitNarration,
|
|
28
21
|
stepLabel,
|
|
29
22
|
stopTurn,
|
|
30
23
|
summarizeTools,
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
toPermission,
|
|
25
|
+
toolName,
|
|
26
|
+
toolNames
|
|
27
|
+
} from "../chunks/chunk-JQEB37IY.js";
|
|
33
28
|
import {
|
|
34
29
|
applyReferences,
|
|
35
30
|
cleanUserText,
|
|
@@ -37,13 +32,10 @@ import {
|
|
|
37
32
|
systemNoteOf
|
|
38
33
|
} from "../chunks/chunk-6U545WJG.js";
|
|
39
34
|
export {
|
|
40
|
-
RESTART_NOTICE,
|
|
41
|
-
RESUME_TEXT,
|
|
42
35
|
TOOL_VERBS_EN,
|
|
43
36
|
TOOL_VERBS_ES,
|
|
44
|
-
appendAgentMessages,
|
|
45
|
-
applyHistory,
|
|
46
37
|
applyReferences,
|
|
38
|
+
argsDetail,
|
|
47
39
|
beginSend,
|
|
48
40
|
cleanReplyOption,
|
|
49
41
|
cleanUserText,
|
|
@@ -56,19 +48,17 @@ export {
|
|
|
56
48
|
isNarration,
|
|
57
49
|
isRunning,
|
|
58
50
|
lastUserTurn,
|
|
51
|
+
messagesToTurns,
|
|
59
52
|
narrationToMarkdown,
|
|
60
|
-
|
|
61
|
-
reconcileWith,
|
|
62
|
-
reducePilotEvent,
|
|
53
|
+
reduceAgUiEvent,
|
|
63
54
|
resolvePermission,
|
|
64
|
-
resumeMode,
|
|
65
|
-
sendAccepted,
|
|
66
55
|
sendFailed,
|
|
67
|
-
sendRejectedBusy,
|
|
68
56
|
splitNarration,
|
|
69
57
|
stepLabel,
|
|
70
58
|
stopTurn,
|
|
71
59
|
summarizeTools,
|
|
72
60
|
systemNoteOf,
|
|
73
|
-
|
|
61
|
+
toPermission,
|
|
62
|
+
toolName,
|
|
63
|
+
toolNames
|
|
74
64
|
};
|
package/dist/core/reducer.d.ts
CHANGED
|
@@ -1,54 +1,36 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const RESTART_NOTICE = "El servidor se reinici\u00F3 a media respuesta. Vuelve a enviar el mensaje.";
|
|
4
|
-
/** Lo que se ve en el hilo al retomar (el servidor manda al agente la continuación entera). */
|
|
5
|
-
export declare const RESUME_TEXT = "Contin\u00FAa donde te quedaste.";
|
|
1
|
+
import type { Interrupt, Message } from "@ag-ui/core";
|
|
2
|
+
import type { Attachment, Decision, PermissionRequest, PilotState, Turn } from "./types";
|
|
6
3
|
export declare function createPilotState(turns?: Turn[]): PilotState;
|
|
4
|
+
type Ev = {
|
|
5
|
+
type: string;
|
|
6
|
+
[k: string]: any;
|
|
7
|
+
};
|
|
8
|
+
/** Los argumentos de una tool en corto, para el renglón del paso: «job: purge-notifications». */
|
|
9
|
+
export declare function argsDetail(json?: string): string | undefined;
|
|
10
|
+
/** Un `Interrupt` de AG-UI como tarjeta: título, herramienta (por su toolCallId) y vencimiento. */
|
|
11
|
+
export declare function toPermission(i: Interrupt, turns: Turn[], clockOffset?: number): PermissionRequest;
|
|
7
12
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
13
|
+
* El hilo guardado (mensajes AG-UI) como turnos: cada mensaje del usuario abre uno; lo que sigue del
|
|
14
|
+
* asistente y de las herramientas se junta en un turno, con sus pasos y su narración.
|
|
10
15
|
*/
|
|
11
|
-
export declare function
|
|
12
|
-
/** `
|
|
13
|
-
export declare function
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/** El servidor aceptó el encargo. `inFlight` = había turno en vuelo al mandar. */
|
|
20
|
-
export declare function sendAccepted(prev: PilotState, r: SendResult, inFlight: boolean, now?: number): PilotState;
|
|
21
|
-
/**
|
|
22
|
-
* El servidor ya tiene un turno corriendo (409 `turn_busy`): el mensaje de este cliente NO entró.
|
|
23
|
-
* Se quita de la pantalla y se avisa; el transporte se re-engancha al turno que sí corre.
|
|
24
|
-
*/
|
|
25
|
-
export declare function sendRejectedBusy(prev: PilotState, message: string): PilotState;
|
|
26
|
-
/** El encargo fue rechazado (sin saldo, sin cuenta…): se DICE, para que no se quede pensando. */
|
|
27
|
-
export declare function sendFailed(prev: PilotState, message: string, needsLogin?: boolean): PilotState;
|
|
28
|
-
/** Detener el turno en curso (el POST de cancelar lo hace el transporte). */
|
|
16
|
+
export declare function messagesToTurns(messages: Message[]): Turn[];
|
|
17
|
+
/** Un evento AG-UI → estado nuevo. `now` se inyecta para que el reductor sea puro. */
|
|
18
|
+
export declare function reduceAgUiEvent(prev: PilotState, e: Ev, now?: number): PilotState;
|
|
19
|
+
/** El usuario manda un mensaje (o contesta una tarjeta: `text` vacío, sin burbuja). */
|
|
20
|
+
export declare function beginSend(prev: PilotState, text: string, attachments?: Attachment[], now?: number): PilotState;
|
|
21
|
+
/** El servidor no aceptó el encargo (HTTP): se DICE, para que no se quede pensando. */
|
|
22
|
+
export declare function sendFailed(prev: PilotState, message: string): PilotState;
|
|
23
|
+
/** Detener: el cliente cortó la conexión (el servidor corta el run). */
|
|
29
24
|
export declare function stopTurn(prev: PilotState): PilotState;
|
|
30
25
|
/** Quita el último intercambio (las respuestas del final y el último mensaje del usuario). */
|
|
31
26
|
export declare function dropLastExchange(prev: PilotState): PilotState;
|
|
32
|
-
/**
|
|
33
|
-
* El usuario contestó una tarjeta: sale de las abiertas y queda anotada en la última respuesta
|
|
34
|
-
* («Aprobaste: correr la purga»). `resolved: false` = ya no estaba abierta (venció o la contestó otro).
|
|
35
|
-
*/
|
|
36
|
-
export declare function resolvePermission(prev: PilotState, id: string, optionId: string, resolved: boolean, detail?: string,
|
|
37
|
-
/** La tarjeta como estaba al contestarla (el stream pudo retirarla mientras tanto). */
|
|
38
|
-
asked?: PermissionRequest): PilotState;
|
|
39
|
-
/**
|
|
40
|
-
* El historial guardado (al montar): el hilo, si la pantalla sigue vacía, y las tarjetas de permiso
|
|
41
|
-
* que siguen abiertas (sin duplicar las que el stream ya trajo).
|
|
42
|
-
*/
|
|
43
|
-
export declare function applyHistory(prev: PilotState, turns: Turn[], permissions?: PermissionRequest[]): PilotState;
|
|
44
|
-
/** Un mensaje del agente que entró fuera de un turno (el remate de los subagentes). */
|
|
45
|
-
export declare function appendAgentMessages(prev: PilotState, texts: string[]): PilotState;
|
|
46
|
-
/** La copia del hilo cambió: trae los mensajes que el usuario mandó desde OTRO cliente. Sólo en reposo. */
|
|
47
|
-
export declare function reconcileWith(prev: PilotState, fresh: Turn[]): PilotState;
|
|
48
|
-
/** El último mensaje del usuario (para reintentar o retomar). */
|
|
27
|
+
/** El último mensaje del usuario (para reintentar). */
|
|
49
28
|
export declare function lastUserTurn(turns: Turn[]): Turn | null;
|
|
50
29
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
30
|
+
* El usuario contestó (o dejó vencer) una tarjeta: sale de las abiertas y queda anotada en la última
|
|
31
|
+
* respuesta («Aprobaste: correr la purga»).
|
|
53
32
|
*/
|
|
54
|
-
export declare function
|
|
33
|
+
export declare function resolvePermission(prev: PilotState, id: string, status: Decision["status"], asked?: PermissionRequest): PilotState;
|
|
34
|
+
/** `expiresAt` (ISO o epoch ms) → epoch ms. */
|
|
35
|
+
export declare function expiryMs(v: string | number): number;
|
|
36
|
+
export {};
|
package/dist/core/steps.d.ts
CHANGED
|
@@ -10,7 +10,15 @@ export interface ToolVerb {
|
|
|
10
10
|
export type ToolVerbs = Record<string, ToolVerb>;
|
|
11
11
|
/** ¿Sigue corriendo? `pending` también: es el instante entre pedirla y arrancarla. */
|
|
12
12
|
export declare const isRunning: (t: ToolEntry) => boolean;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Los nombres con los que se puede buscar el verbo/ícono de una herramienta, del más específico al
|
|
15
|
+
* menos: el título tal cual, y sin el prefijo de MCP. Los MCP la nombran `mcp__servidor__tool` (dos
|
|
16
|
+
* guiones bajos) o `mcp_servidor_tool` (uno, visto en EasyBits); como el servidor y la tool también
|
|
17
|
+
* llevan guiones bajos, con uno solo se prueban todos los cortes: `mcp_easy_bits_list_crons` →
|
|
18
|
+
* `easy_bits_list_crons`, `bits_list_crons`, `list_crons`, `crons`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function toolNames(t: ToolEntry): string[];
|
|
21
|
+
/** El nombre «corto» de la herramienta (sin el prefijo de MCP de dos guiones bajos). */
|
|
14
22
|
export declare function toolName(t: ToolEntry): string | null;
|
|
15
23
|
/** El rótulo de un paso: el verbo de su nombre, o el título que manda el servidor, o su clase. */
|
|
16
24
|
export declare function stepLabel(t: ToolEntry, verbs: ToolVerbs, fallback?: string): string;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,86 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
3
|
-
/** Un
|
|
4
|
-
export interface ModelOption {
|
|
5
|
-
value: string;
|
|
6
|
-
name: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Un adjunto listo para el agente: base64 sin prefijo + su MIME, o una URL ya subida.
|
|
10
|
-
* Viaja en el cuerpo del POST como `images` (nombre histórico del contrato).
|
|
11
|
-
*/
|
|
1
|
+
import type { BaseEvent, Interrupt, Message, RunAgentInput } from "@ag-ui/core";
|
|
2
|
+
export type { BaseEvent, Interrupt, Message, RunAgentInput };
|
|
3
|
+
/** Un adjunto del mensaje del usuario (viaja como parte de contenido AG-UI). */
|
|
12
4
|
export interface Attachment {
|
|
13
5
|
name?: string;
|
|
14
6
|
mimeType: string;
|
|
15
|
-
/** Base64 sin el prefijo `data
|
|
16
|
-
data
|
|
17
|
-
/** URL del archivo ya subido (lo
|
|
18
|
-
|
|
19
|
-
/** Id del archivo en la app, si la app lo guarda. */
|
|
20
|
-
fileId?: string;
|
|
7
|
+
/** Base64 sin el prefijo `data:` (imágenes y texto que caben en el mensaje). */
|
|
8
|
+
data?: string;
|
|
9
|
+
/** URL del archivo ya subido (lo demás). */
|
|
10
|
+
url?: string;
|
|
21
11
|
}
|
|
22
|
-
/** Un paso del agente
|
|
12
|
+
/** Un paso del agente: una llamada a herramienta (TOOL_CALL_*). */
|
|
23
13
|
export interface ToolEntry {
|
|
24
14
|
id: string;
|
|
15
|
+
/** El nombre de la herramienta (`toolCallName`): es la llave de los verbos de la app. */
|
|
25
16
|
title?: string;
|
|
26
17
|
kind?: string;
|
|
18
|
+
/** `in_progress` mientras corre; `completed` | `failed` con su resultado; `pending` = espera
|
|
19
|
+
* aprobación; `cancelled` = el run se detuvo antes de que terminara. */
|
|
27
20
|
status?: string;
|
|
28
21
|
path?: string;
|
|
29
|
-
/**
|
|
22
|
+
/** Los argumentos, en corto («job: purge-notifications»). */
|
|
30
23
|
detail?: string;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export interface Delivery {
|
|
34
|
-
kind: "file" | "artifact";
|
|
35
|
-
name: string;
|
|
36
|
-
fileId?: string;
|
|
37
|
-
/** Documento editable de la app (Ghosty: `@ghostystudio/docs`). */
|
|
38
|
-
docId?: string;
|
|
39
|
-
mime?: string;
|
|
40
|
-
size?: number;
|
|
41
|
-
/** Captura de pantalla del navegador: se pinta en su tira, no como entrega suelta. */
|
|
42
|
-
capture?: boolean;
|
|
43
|
-
raw?: Record<string, unknown>;
|
|
44
|
-
}
|
|
45
|
-
/** Una sección de la página que el turno arma (constructor por secciones). */
|
|
46
|
-
export interface PageBuildSection {
|
|
47
|
-
id: string;
|
|
48
|
-
label: string;
|
|
49
|
-
kind: string;
|
|
50
|
-
status: "pending" | "building" | "done" | "failed";
|
|
51
|
-
html?: string;
|
|
52
|
-
}
|
|
53
|
-
/** La revisión de la página armada: corriendo, o terminada con sus arreglos. */
|
|
54
|
-
export interface PageReview {
|
|
55
|
-
status: "running" | "done";
|
|
56
|
-
fixes: {
|
|
57
|
-
name: string;
|
|
58
|
-
sectionId: string;
|
|
59
|
-
}[];
|
|
60
|
-
skipped: string[];
|
|
61
|
-
thumb?: string | null;
|
|
62
|
-
seconds?: number;
|
|
63
|
-
}
|
|
64
|
-
/** Una página que el turno está armando, por `pageId` (eventos `page-plan` … `page-ready`). */
|
|
65
|
-
export interface PageBuild {
|
|
66
|
-
pageId: string;
|
|
67
|
-
title: string;
|
|
68
|
-
/** Opaco para Piloto: lo interpreta quien pinta la página (slot `renderDeliveries`). */
|
|
69
|
-
theme: unknown;
|
|
70
|
-
sections: PageBuildSection[];
|
|
71
|
-
startedAt: number;
|
|
72
|
-
readyAt?: number;
|
|
73
|
-
url?: string | null;
|
|
74
|
-
n?: number;
|
|
75
|
-
error?: string;
|
|
76
|
-
mode?: "build" | "edit";
|
|
77
|
-
focus?: {
|
|
78
|
-
sectionId: string;
|
|
79
|
-
nodeId: string;
|
|
80
|
-
};
|
|
81
|
-
editLabel?: string;
|
|
82
|
-
editSummary?: string;
|
|
83
|
-
review?: PageReview;
|
|
24
|
+
/** Los argumentos en JSON tal como llegaron (TOOL_CALL_ARGS). */
|
|
25
|
+
args?: string;
|
|
84
26
|
}
|
|
85
27
|
export interface Usage {
|
|
86
28
|
used: number;
|
|
@@ -89,13 +31,17 @@ export interface Usage {
|
|
|
89
31
|
input?: number;
|
|
90
32
|
output?: number;
|
|
91
33
|
}
|
|
34
|
+
/** Una tarjeta de aprobación ya contestada. */
|
|
35
|
+
export interface Decision {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
status: "approved" | "rejected" | "expired" | "cancelled";
|
|
39
|
+
detail?: string;
|
|
40
|
+
}
|
|
92
41
|
export interface Turn {
|
|
93
42
|
role: "user" | "assistant";
|
|
94
43
|
text: string;
|
|
95
|
-
/**
|
|
96
|
-
arrived?: boolean;
|
|
97
|
-
deliveries?: Delivery[];
|
|
98
|
-
/** Cuánto tardó, en segundos. Se rellena al cerrar el turno. */
|
|
44
|
+
/** Cuánto tardó, en segundos (sólo los turnos vistos en vivo). */
|
|
99
45
|
seconds?: number;
|
|
100
46
|
thought?: string;
|
|
101
47
|
tools?: ToolEntry[];
|
|
@@ -103,48 +49,33 @@ export interface Turn {
|
|
|
103
49
|
cuts?: number[];
|
|
104
50
|
attachments?: Attachment[];
|
|
105
51
|
usage?: Usage;
|
|
106
|
-
/** Lo que el usuario decidió en las tarjetas de
|
|
52
|
+
/** Lo que el usuario decidió en las tarjetas de este turno (sólo en vivo). */
|
|
107
53
|
decisions?: Decision[];
|
|
108
|
-
/** Mensaje del usuario que ENTRÓ al turno en vuelo (steer): la respuesta sigue arriba. */
|
|
109
|
-
steer?: boolean;
|
|
110
|
-
pages?: PageBuild[];
|
|
111
|
-
/** El servidor ya está planeando una página (antes de que llegue su plan). */
|
|
112
|
-
planning?: boolean;
|
|
113
|
-
planningAt?: number;
|
|
114
|
-
}
|
|
115
|
-
/** Un turno que se cortó por falla del servidor (deploy, caja caída). Lo dice el servidor. */
|
|
116
|
-
export interface Interrupted {
|
|
117
|
-
reason: string;
|
|
118
|
-
turnId?: string;
|
|
119
|
-
/** El servidor puede CONTINUAR ese turno (EasyBits: `continueTurnId`). */
|
|
120
|
-
canContinue?: boolean;
|
|
121
54
|
}
|
|
122
|
-
/** Una
|
|
123
|
-
export interface Decision {
|
|
124
|
-
id: string;
|
|
125
|
-
title: string;
|
|
126
|
-
status: "approved" | "rejected" | "expired";
|
|
127
|
-
/** Lo que devolvió la app al resolverla (p. ej. «ejecutada»). */
|
|
128
|
-
detail?: string;
|
|
129
|
-
}
|
|
130
|
-
/** Una opción de un pedido de permiso, tal cual la manda el agente (ACP). */
|
|
55
|
+
/** Una opción de la tarjeta de aprobación. */
|
|
131
56
|
export interface PermissionOption {
|
|
132
57
|
optionId: string;
|
|
133
58
|
name: string;
|
|
134
|
-
/** `allow_once` | `
|
|
59
|
+
/** `allow_once` | `reject_once`. */
|
|
135
60
|
kind?: string;
|
|
136
61
|
}
|
|
137
|
-
/**
|
|
62
|
+
/** Una aprobación pendiente (un `Interrupt` de AG-UI, listo para pintar). */
|
|
138
63
|
export interface PermissionRequest {
|
|
64
|
+
/** El `id` del interrupt: con él se contesta (`resume[].interruptId`). */
|
|
139
65
|
id: string;
|
|
140
66
|
title: string;
|
|
141
67
|
tool?: string;
|
|
68
|
+
toolCallId?: string;
|
|
69
|
+
reason?: string;
|
|
142
70
|
options: PermissionOption[];
|
|
71
|
+
/** Hasta cuándo se puede contestar (ISO, reloj del SERVIDOR). */
|
|
72
|
+
expiresAt?: string | number;
|
|
143
73
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
74
|
+
* El mismo vencimiento en el reloj de ESTE navegador (epoch ms): `expiresAt` menos la hora del
|
|
75
|
+
* servidor al mandar el evento, más la hora local al recibirlo. Así un reloj local desfasado no
|
|
76
|
+
* adelanta ni atrasa la cuenta regresiva.
|
|
146
77
|
*/
|
|
147
|
-
|
|
78
|
+
deadline?: number;
|
|
148
79
|
}
|
|
149
80
|
/** Lo que una transición pide hacer FUERA del estado (avisos a la app). */
|
|
150
81
|
export type PilotEffect = {
|
|
@@ -152,85 +83,37 @@ export type PilotEffect = {
|
|
|
152
83
|
} | {
|
|
153
84
|
type: "turn-done";
|
|
154
85
|
text: string;
|
|
155
|
-
|
|
86
|
+
runId?: string;
|
|
156
87
|
seconds?: number;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
reason: string;
|
|
160
|
-
turnId?: string;
|
|
161
|
-
} | {
|
|
162
|
-
type: "needs-login";
|
|
88
|
+
error?: string;
|
|
89
|
+
interrupted?: boolean;
|
|
163
90
|
} | {
|
|
164
91
|
type: "title";
|
|
165
92
|
title?: string;
|
|
166
|
-
} | {
|
|
167
|
-
type: "disconnected";
|
|
168
93
|
};
|
|
169
94
|
export interface PilotState {
|
|
170
95
|
turns: Turn[];
|
|
96
|
+
/** Hay un run corriendo. */
|
|
171
97
|
busy: boolean;
|
|
172
|
-
connected: boolean;
|
|
173
|
-
phase: ConnectPhase;
|
|
174
98
|
error: string | null;
|
|
175
99
|
notice: string | null;
|
|
176
100
|
usage: Usage | null;
|
|
177
|
-
|
|
178
|
-
currentModel: string | null;
|
|
179
|
-
/** Qué puede el agente. Empieza en `true` para no bloquear mientras se conecta. */
|
|
180
|
-
canSeeImages: boolean;
|
|
181
|
-
/** El último turno se cortó por falla del servidor: el chat ofrece Retomar. */
|
|
182
|
-
interrupted: Interrupted | null;
|
|
183
|
-
/** El turno sigue en OTRA instancia del servidor (deploy azul/verde): «sigo trabajando». */
|
|
184
|
-
elsewhere: boolean;
|
|
185
|
-
/** Permisos abiertos, en el orden en que llegaron. */
|
|
101
|
+
/** Aprobaciones abiertas (del último RUN_FINISHED con outcome interrupt). */
|
|
186
102
|
permissions: PermissionRequest[];
|
|
187
103
|
/** Cuándo empezó el turno que ESTE cliente encargó (0 = ninguno). */
|
|
188
104
|
turnStartedAt: number;
|
|
189
|
-
|
|
190
|
-
streaming: boolean;
|
|
191
|
-
/** El `turnId` del turno que este cliente encargó (lo devuelve el POST). */
|
|
192
|
-
currentTurnId: string | null;
|
|
193
|
-
/** Cuántas veces se abrió el stream: >1 = reconexión. */
|
|
194
|
-
connections: number;
|
|
195
|
-
/** El servidor avisó (`caps.needAccount`) que hace falta cuenta: se avisa al cerrar el turno. */
|
|
196
|
-
needAccount: boolean;
|
|
197
|
-
/** Cada cuánto promete el servidor su latido (`started.latidoMs`). */
|
|
198
|
-
heartbeatMs: number | null;
|
|
105
|
+
runId: string | null;
|
|
199
106
|
/** Efectos de la ÚLTIMA transición. El hook los ejecuta y los descarta. */
|
|
200
107
|
effects: PilotEffect[];
|
|
201
108
|
}
|
|
202
|
-
/** Lo que se le pide al transporte al mandar un mensaje. */
|
|
203
|
-
export interface SendInput {
|
|
204
|
-
text: string;
|
|
205
|
-
attachments: Attachment[];
|
|
206
|
-
/** Es el primer mensaje del hilo (el servidor lo bautiza al cerrar el turno). */
|
|
207
|
-
firstTurn: boolean;
|
|
208
|
-
/** «Retomar» un turno cortado: el servidor arma la continuación. */
|
|
209
|
-
resume?: boolean;
|
|
210
|
-
/** Con `resume`: el turno a continuar, si el servidor lo dijo (`interrupted.turnId`). */
|
|
211
|
-
resumeTurnId?: string;
|
|
212
|
-
/** Lo que el usuario ve en pantalla, para este turno. */
|
|
213
|
-
context?: unknown;
|
|
214
|
-
/** Las referencias que viajaron en el texto, también estructuradas. */
|
|
215
|
-
references?: Reference[];
|
|
216
|
-
}
|
|
217
|
-
/** Lo que contesta el servidor al encargo. */
|
|
218
|
-
export interface SendResult {
|
|
219
|
-
/** El mensaje entró al turno en vuelo (steer). */
|
|
220
|
-
injected?: boolean;
|
|
221
|
-
/** `queued` = la caja está despertando. */
|
|
222
|
-
state?: string;
|
|
223
|
-
turnId?: string;
|
|
224
|
-
}
|
|
225
109
|
/**
|
|
226
110
|
* Una referencia que acompaña al mensaje (una tarjeta del tablero, un elemento señalado).
|
|
227
111
|
* Con `prompt`, ese renglón va ANTES del mensaje; sin él, las etiquetas van juntas como
|
|
228
|
-
* `[#12 Rosa, #7 Javier]
|
|
112
|
+
* `[#12 Rosa, #7 Javier] `.
|
|
229
113
|
*/
|
|
230
114
|
export interface Reference {
|
|
231
115
|
id: string;
|
|
232
116
|
label: string;
|
|
233
117
|
prompt?: string;
|
|
234
|
-
/** Texto secundario del chip («el texto señalado»). */
|
|
235
118
|
hint?: string;
|
|
236
119
|
}
|
package/dist/react/Bubble.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type ReplyOptions } from "../core/options";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Turn, Usage } from "../core/types";
|
|
4
4
|
export declare function UserBubble({ turn }: {
|
|
5
5
|
turn: Turn;
|
|
6
6
|
}): import("react").JSX.Element;
|
|
@@ -23,10 +23,6 @@ export declare function TurnFooter({ text, seconds, onRetry, showCopy, showDurat
|
|
|
23
23
|
showCopy?: boolean;
|
|
24
24
|
showDuration?: boolean;
|
|
25
25
|
}): import("react").JSX.Element;
|
|
26
|
-
/** Las entregas por defecto: una ficha por archivo (las apps pintan las suyas con `renderDeliveries`). */
|
|
27
|
-
export declare function DeliveryChips({ deliveries }: {
|
|
28
|
-
deliveries: Delivery[];
|
|
29
|
-
}): import("react").JSX.Element | null;
|
|
30
26
|
export interface AgentBubbleProps {
|
|
31
27
|
turn: Turn;
|
|
32
28
|
/** El turno sigue escribiéndose. */
|
|
@@ -37,7 +33,7 @@ export interface AgentBubbleProps {
|
|
|
37
33
|
showUsage?: boolean;
|
|
38
34
|
showCopy?: boolean;
|
|
39
35
|
showDuration?: boolean;
|
|
40
|
-
/**
|
|
36
|
+
/** Lo que la app quiera pintar bajo la respuesta (archivos, tarjetas propias). */
|
|
41
37
|
renderDeliveries?: (turn: Turn, live: boolean) => ReactNode;
|
|
42
38
|
}
|
|
43
39
|
export declare function AgentBubble({ turn, live, onRetry, onOption, showUsage, showCopy, showDuration, renderDeliveries }: AgentBubbleProps): import("react").JSX.Element;
|
package/dist/react/Composer.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import type { Attachment,
|
|
2
|
+
import type { Attachment, Reference } from "../core/types";
|
|
3
|
+
/** Un modelo que la app ofrece elegir (AG-UI no lo define: la app lo manda en `forwardedProps`). */
|
|
4
|
+
export interface ModelOption {
|
|
5
|
+
value: string;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
3
8
|
/** Lo que devuelve la app al subir un archivo: su URL (y su id, si lo guarda). */
|
|
4
9
|
export interface UploadResult {
|
|
5
10
|
url: string;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { Decision, PermissionOption, PermissionRequest } from "../core/types";
|
|
2
|
-
import type { PermissionAnswer } from "./usePilot";
|
|
3
2
|
/** Las opciones de rechazo van primero y discretas; las de aprobar, al final y en color. */
|
|
4
3
|
export declare const isRejectOption: (o: PermissionOption) => boolean;
|
|
5
4
|
export declare function ConfirmCard({ request, onRespond, onSettled, onExpire, }: {
|
|
6
5
|
request: PermissionRequest;
|
|
7
|
-
/** Contesta
|
|
8
|
-
onRespond: (id: string,
|
|
6
|
+
/** Contesta: `approved` viaja como `payload` del `resume`. */
|
|
7
|
+
onRespond: (id: string, approved: boolean) => void;
|
|
9
8
|
/** El sello ya se vio: anotar la decisión y retirar la tarjeta. */
|
|
10
|
-
onSettled?: (id: string,
|
|
9
|
+
onSettled?: (id: string, status: Decision["status"]) => void;
|
|
11
10
|
/** Venció sin contestarse. */
|
|
12
11
|
onExpire?: (id: string) => void;
|
|
13
12
|
}): import("react").JSX.Element;
|
package/dist/react/Piloto.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { PilotTransport } from "../transport";
|
|
|
5
5
|
import { type UploadResult } from "./Composer";
|
|
6
6
|
import { type MarkdownOptions, type PilotIcon, type PilotTheme } from "./context";
|
|
7
7
|
import { type PilotStrings } from "./strings";
|
|
8
|
-
import { type
|
|
8
|
+
import { type Pilot, type UsePilotOptions } from "./usePilot";
|
|
9
9
|
export interface PilotoFeatures {
|
|
10
10
|
/** Botones de adjuntar. Default: sí si hay `upload`. */
|
|
11
11
|
attachments?: boolean;
|
|
@@ -15,15 +15,13 @@ export interface PilotoFeatures {
|
|
|
15
15
|
copy?: boolean;
|
|
16
16
|
/** Tokens y costo bajo cada respuesta. Default: sí. */
|
|
17
17
|
usage?: boolean;
|
|
18
|
-
/** Selector de modelo (si el agente ofrece varios). Default: sí. */
|
|
19
|
-
models?: boolean;
|
|
20
18
|
/** Las opciones finales de la última respuesta como botones. Default: sí. */
|
|
21
19
|
replyOptions?: boolean;
|
|
22
20
|
/** «· 12 s» junto a la frase de espera. Default: sí. */
|
|
23
21
|
duration?: boolean;
|
|
24
22
|
}
|
|
25
23
|
export interface PilotoSlots {
|
|
26
|
-
/**
|
|
24
|
+
/** Lo que la app pinte bajo cada respuesta (archivos, tarjetas propias). */
|
|
27
25
|
renderDeliveries?: (turn: Turn, live: boolean) => ReactNode;
|
|
28
26
|
/** Botones propios en la barra del composer. */
|
|
29
27
|
composerExtras?: ReactNode;
|
|
@@ -61,12 +59,7 @@ export interface PilotoProps extends UsePilotOptions {
|
|
|
61
59
|
voiceNoteText?: (transcript: string) => string;
|
|
62
60
|
features?: PilotoFeatures;
|
|
63
61
|
/**
|
|
64
|
-
*
|
|
65
|
-
* `transport.respondPermission`. Devuelve `{resolved:false}` si ya no estaba abierto.
|
|
66
|
-
*/
|
|
67
|
-
onPermission?: PermissionHandler;
|
|
68
|
-
/**
|
|
69
|
-
* Una pregunta lista en la caja (sin mandarla) y el foco en ella: al abrir el copiloto desde una
|
|
62
|
+
* Una pregunta lista en la caja (sin mandarla) y el foco en ella: al abrir el piloto desde una
|
|
70
63
|
* fila («Pídeselo»). Cambiar el texto —o `key`, para repetir el mismo— la vuelve a poner.
|
|
71
64
|
*/
|
|
72
65
|
draft?: string | {
|