ghostykit 0.3.2 → 0.4.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.
@@ -1,86 +1,27 @@
1
- /** Por dónde va la conexión con el agente antes de que conteste. */
2
- export type ConnectPhase = "waking" | "connecting" | "session";
3
- /** Un modelo que el agente ofrece para la sesión (selector ACP). */
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:`. Vacío cuando el archivo viaja por `uri`. */
16
- data: string;
17
- /** URL del archivo ya subido (lo que el agente descarga cuando no es imagen ni texto). */
18
- uri?: string;
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 (una herramienta), según ACP: pending → in_progress → completed | failed. */
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 aprobación. */
27
19
  status?: string;
28
20
  path?: string;
29
- /** Qué hace, en palabras de persona (el comando, el archivo, el prompt de la imagen). */
21
+ /** Los argumentos, en corto («job: purge-notifications»). */
30
22
  detail?: string;
31
- }
32
- /** Lo que el agente ENTREGÓ en el turno (evento `artifact`). `raw` es el payload tal cual. */
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;
23
+ /** Los argumentos en JSON tal como llegaron (TOOL_CALL_ARGS). */
24
+ args?: string;
84
25
  }
85
26
  export interface Usage {
86
27
  used: number;
@@ -89,13 +30,17 @@ export interface Usage {
89
30
  input?: number;
90
31
  output?: number;
91
32
  }
33
+ /** Una tarjeta de aprobación ya contestada. */
34
+ export interface Decision {
35
+ id: string;
36
+ title: string;
37
+ status: "approved" | "rejected" | "expired" | "cancelled";
38
+ detail?: string;
39
+ }
92
40
  export interface Turn {
93
41
  role: "user" | "assistant";
94
42
  text: string;
95
- /** Llegó entero fuera de un turno (el remate de los subagentes): se escribe al ritmo. */
96
- arrived?: boolean;
97
- deliveries?: Delivery[];
98
- /** Cuánto tardó, en segundos. Se rellena al cerrar el turno. */
43
+ /** Cuánto tardó, en segundos (sólo los turnos vistos en vivo). */
99
44
  seconds?: number;
100
45
  thought?: string;
101
46
  tools?: ToolEntry[];
@@ -103,47 +48,26 @@ export interface Turn {
103
48
  cuts?: number[];
104
49
  attachments?: Attachment[];
105
50
  usage?: Usage;
106
- /** Lo que el usuario decidió en las tarjetas de permiso de este turno (sólo en vivo). */
51
+ /** Lo que el usuario decidió en las tarjetas de este turno (sólo en vivo). */
107
52
  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
- }
122
- /** Una tarjeta de permiso ya contestada. */
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
53
  }
130
- /** Una opción de un pedido de permiso, tal cual la manda el agente (ACP). */
54
+ /** Una opción de la tarjeta de aprobación. */
131
55
  export interface PermissionOption {
132
56
  optionId: string;
133
57
  name: string;
134
- /** `allow_once` | `allow_always` | `reject_once` | `reject_always` | otra. */
58
+ /** `allow_once` | `reject_once`. */
135
59
  kind?: string;
136
60
  }
137
- /** El agente pide permiso antes de algo riesgoso: el turno está DETENIDO hasta que alguien conteste. */
61
+ /** Una aprobación pendiente (un `Interrupt` de AG-UI, listo para pintar). */
138
62
  export interface PermissionRequest {
63
+ /** El `id` del interrupt: con él se contesta (`resume[].interruptId`). */
139
64
  id: string;
140
65
  title: string;
141
66
  tool?: string;
67
+ toolCallId?: string;
68
+ reason?: string;
142
69
  options: PermissionOption[];
143
- /**
144
- * Hasta cuándo se puede contestar (ISO o epoch ms). Una tarjeta CON vencimiento no depende del
145
- * turno (EasyBits: la propuesta vive 15 min aunque el turno ya cerró) y sobrevive al `done`.
146
- */
70
+ /** Hasta cuándo se puede contestar (ISO). */
147
71
  expiresAt?: string | number;
148
72
  }
149
73
  /** Lo que una transición pide hacer FUERA del estado (avisos a la app). */
@@ -152,85 +76,37 @@ export type PilotEffect = {
152
76
  } | {
153
77
  type: "turn-done";
154
78
  text: string;
155
- turnId?: string;
79
+ runId?: string;
156
80
  seconds?: number;
157
- } | {
158
- type: "turn-interrupted";
159
- reason: string;
160
- turnId?: string;
161
- } | {
162
- type: "needs-login";
81
+ error?: string;
82
+ interrupted?: boolean;
163
83
  } | {
164
84
  type: "title";
165
85
  title?: string;
166
- } | {
167
- type: "disconnected";
168
86
  };
169
87
  export interface PilotState {
170
88
  turns: Turn[];
89
+ /** Hay un run corriendo. */
171
90
  busy: boolean;
172
- connected: boolean;
173
- phase: ConnectPhase;
174
91
  error: string | null;
175
92
  notice: string | null;
176
93
  usage: Usage | null;
177
- models: ModelOption[];
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. */
94
+ /** Aprobaciones abiertas (del último RUN_FINISHED con outcome interrupt). */
186
95
  permissions: PermissionRequest[];
187
96
  /** Cuándo empezó el turno que ESTE cliente encargó (0 = ninguno). */
188
97
  turnStartedAt: number;
189
- /** Hay una burbuja del asistente recibiendo eventos del turno en curso. */
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;
98
+ runId: string | null;
199
99
  /** Efectos de la ÚLTIMA transición. El hook los ejecuta y los descarta. */
200
100
  effects: PilotEffect[];
201
101
  }
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
102
  /**
226
103
  * Una referencia que acompaña al mensaje (una tarjeta del tablero, un elemento señalado).
227
104
  * Con `prompt`, ese renglón va ANTES del mensaje; sin él, las etiquetas van juntas como
228
- * `[#12 Rosa, #7 Javier] ` (el formato del tablero de Ghosty).
105
+ * `[#12 Rosa, #7 Javier] `.
229
106
  */
230
107
  export interface Reference {
231
108
  id: string;
232
109
  label: string;
233
110
  prompt?: string;
234
- /** Texto secundario del chip («el texto señalado»). */
235
111
  hint?: string;
236
112
  }
@@ -1,6 +1,6 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { type ReplyOptions } from "../core/options";
3
- import type { Delivery, Turn, Usage } from "../core/types";
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
- /** Las entregas (y lo que la app quiera bajo la respuesta). Sin esto, fichas simples. */
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;
@@ -1,5 +1,10 @@
1
1
  import { type ReactNode } from "react";
2
- import type { Attachment, ModelOption, Reference } from "../core/types";
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 (el transporte o la ruta de la app). `{resolved:false}` = ya no estaba abierta. */
8
- onRespond: (id: string, optionId: string) => Promise<PermissionAnswer> | PermissionAnswer;
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, optionId: string, answer: PermissionAnswer) => void;
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;
@@ -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 PermissionHandler, type Pilot, type UsePilotOptions } from "./usePilot";
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
- /** Las entregas de cada respuesta (archivos, páginas, tarjetas propias). */
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
- * Contestar un permiso (p. ej. el POST de aprobación de la app, con su sesión). Default:
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 | {
@@ -1,19 +1,7 @@
1
- import { type ReactNode } from "react";
2
- import type { ConnectPhase } from "../core/types";
3
1
  /** Los tres puntitos de «escribiendo» (color y animación en CSS: `gc-typing`). */
4
2
  export declare function TypingDots(): import("react").JSX.Element;
5
- export declare function WaitLabel({ phase, since, elsewhere, onLost, showDuration, }: {
6
- phase: ConnectPhase;
3
+ export declare function WaitLabel({ since, showDuration, }: {
7
4
  /** Desde que se MANDÓ el mensaje (no desde que se montó la etiqueta). */
8
5
  since?: number | null;
9
- elsewhere?: boolean;
10
- onLost?: () => void;
11
6
  showDuration?: boolean;
12
7
  }): import("react").JSX.Element;
13
- /** Lo que ocupa el hilo mientras se conecta: tres pasos reales en vez de un «Conectando…» mudo. */
14
- export declare function ConnectingState({ phase, error, avatar, onRetry }: {
15
- phase: ConnectPhase;
16
- error: string | null;
17
- avatar?: ReactNode;
18
- onRetry?: () => void;
19
- }): import("react").JSX.Element;
@@ -1,15 +1,15 @@
1
1
  export { Piloto, Piloto as default, type PilotoFeatures, type PilotoHandle, type PilotoProps, type PilotoSlots } from "./Piloto";
2
- export { usePilot, useSseTransport, type PermissionAnswer, type PermissionHandler, type Pilot, type SendOptions, type TurnDoneInfo, type UsePilotOptions } from "./usePilot";
3
- export { AgentBubble, CopyUserMessage, DeliveryChips, ReplyOptionButtons, TurnFooter, UsageStats, UserBubble, type AgentBubbleProps } from "./Bubble";
4
- export { AgentSteps, ClawIcon, DEFAULT_TOOL_ICONS, Narration, ToolRow } from "./Steps";
2
+ export { toAgUiContext, usePilot, type Pilot, type SendOptions, type TurnDoneInfo, type UsePilotOptions } from "./usePilot";
3
+ export { AgentBubble, CopyUserMessage, ReplyOptionButtons, TurnFooter, UsageStats, UserBubble, type AgentBubbleProps } from "./Bubble";
4
+ export { AgentSteps, ArcadeIcon, ClawIcon, DEFAULT_TOOL_ICONS, Narration, RobotArmIcon, ToolRow } from "./Steps";
5
5
  export { LinkSafetyModal, Markdown } from "./Markdown";
6
6
  export { InlineMarkdown, renderInline } from "./InlineMarkdown";
7
7
  export { useTextAtPace } from "./TextAtPace";
8
- export { Composer, ModelPicker, mimeOf, type ComposerProps, type UploadResult } from "./Composer";
8
+ export { Composer, ModelPicker, mimeOf, type ComposerProps, type ModelOption, type UploadResult } from "./Composer";
9
9
  export { ConfirmCard, DecisionLines } from "./ConfirmCard";
10
10
  export { ReferenceChips, Suggestions } from "./Chips";
11
- export { ConnectingState, TypingDots, WaitLabel } from "./Status";
11
+ export { TypingDots, WaitLabel } from "./Status";
12
12
  export { PilotoContext, usePiloto, type MarkdownOptions, type PilotIcon, type PilotoConfig, type PilotTheme } from "./context";
13
13
  export { STRINGS_EN, STRINGS_ES, type PilotStrings } from "./strings";
14
14
  export * from "../core";
15
- export { PilotHttpError, createPostStreamTransport, createSseTransport, readSse, type PilotHistory, type PilotListener, type PilotTransport, type PostStreamTransportOptions, type SseTransportOptions, type SubscribeOptions, } from "../transport";
15
+ export { PilotHttpError, createAgUiTransport, readSse, type AgUiTransportOptions, type PilotTransport, type SseMessage } from "../transport";