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,11 +1,9 @@
1
- import type { ConnectPhase } from "../core/types";
2
1
  export interface PilotStrings {
3
2
  /** Para formatear números y moneda. */
4
3
  numberLocale: string;
5
4
  placeholder: (agentName: string) => string;
6
5
  /** Sin `agentName`. */
7
6
  placeholderDefault: string;
8
- placeholderConnecting: string;
9
7
  send: string;
10
8
  stop: string;
11
9
  uploading: string;
@@ -31,21 +29,12 @@ export interface PilotStrings {
31
29
  voiceFailed: string;
32
30
  model: string;
33
31
  thinking: string;
34
- steered: string;
35
- /** Lo que se ve mientras conecta, por fase (en primera persona: habla el agente). */
36
- waitPhase: Record<ConnectPhase, string>;
37
32
  /** Qué dice el agente de un turno del que sólo sabe cuánto lleva. */
38
33
  howItGoes: (seconds: number) => string;
39
34
  /** Frases propias mientras piensa (rotan cada 4 s en lugar de `howItGoes`). */
40
35
  thinkingPhrases?: string[];
41
36
  stillWorking: string;
42
- cantStart: string;
43
37
  retry: string;
44
- resume: string;
45
- /** Con `interrupted.canContinue`: el servidor continúa ESE turno. */
46
- continueTurn: string;
47
- interrupted: (reason: string) => string;
48
- interruptedOurFault: string;
49
38
  copy: string;
50
39
  copied: string;
51
40
  copyMessage: string;
@@ -59,11 +48,6 @@ export interface PilotStrings {
59
48
  failed: string;
60
49
  step: string;
61
50
  replyOptions: string;
62
- connectSteps: {
63
- label: string;
64
- hint: string;
65
- }[];
66
- connectRetry: string;
67
51
  linkTitle: string;
68
52
  linkCopy: string;
69
53
  linkCopied: string;
@@ -73,14 +57,14 @@ export interface PilotStrings {
73
57
  confirmTitle: string;
74
58
  approve: string;
75
59
  reject: string;
76
- confirmExpired: string;
77
- confirmFailed: string;
78
60
  /** «Vence en 14:32». */
79
61
  expiresIn: (mmss: string) => string;
80
62
  expiredNow: string;
81
63
  decisionApproved: string;
82
64
  decisionRejected: string;
83
65
  decisionExpired: string;
66
+ decisionCancelled: string;
67
+ stampCancelled: string;
84
68
  stampApproved: string;
85
69
  stampRejected: string;
86
70
  stampExpired: string;
@@ -1,67 +1,55 @@
1
- import type { Attachment, Interrupted, PermissionRequest, PilotState, Reference, SendInput, Turn } from "../core/types";
2
- import { type PilotTransport, type SseTransportOptions } from "../transport";
1
+ import type { BaseEvent, RunAgentInput } from "@ag-ui/core";
2
+ import type { Attachment, Decision, PermissionRequest, PilotState, Reference, Turn } from "../core/types";
3
+ import { type PilotTransport } from "../transport";
3
4
  export interface TurnDoneInfo {
4
5
  /** El texto final de la respuesta. */
5
6
  text: string;
6
- turnId?: string;
7
- /** Cuánto tardó (sólo si lo encargó este cliente). */
7
+ runId?: string;
8
+ /** Cuánto tardó. */
8
9
  seconds?: number;
9
- /** Se cortó por falla del servidor (el chat ofrece Retomar). */
10
- interrupted?: Interrupted;
10
+ /** El run terminó en RUN_ERROR. */
11
+ error?: string;
12
+ /** El run se detuvo a pedir aprobación. */
13
+ interrupted?: boolean;
11
14
  }
12
15
  export interface UsePilotOptions {
13
- /** El hilo guardado. Si cambia (la app volvió a leerlo), se reconcilia en reposo. */
16
+ /** El hilo (AG-UI `threadId`). Con él, al montar se pide el hilo guardado (MESSAGES_SNAPSHOT). Sin él, hilo nuevo. */
17
+ threadId?: string;
18
+ /** Turnos para pintar de entrada (sin pedirlos al servidor). */
14
19
  initialTurns?: Turn[];
15
- /** Lo que el usuario ve en pantalla: viaja con CADA turno. Una función se evalúa al mandar. */
20
+ /**
21
+ * Lo que el usuario ve en pantalla: viaja en CADA run como `context` de AG-UI. Un objeto da una
22
+ * entrada por llave (`{description: llave, value: JSON}`); una función se evalúa al mandar.
23
+ */
16
24
  context?: unknown | (() => unknown);
17
25
  onTurnStart?: () => void;
18
26
  /** Fin de turno con su texto: aquí la app re-lee datos, repinta efectos, avisa. */
19
27
  onTurnDone?: (info: TurnDoneInfo) => void;
20
- /** El servidor bautizó el hilo. */
28
+ /** El servidor bautizó el hilo (`CUSTOM ghosty.title`). */
21
29
  onTitle?: (title?: string) => void;
22
- /** El servidor pide cuenta (cupo sin cuenta agotado). */
23
- onNeedsLogin?: () => void;
24
- /** El stream se cerró (el hilo sigue en el servidor y se puede reabrir). */
25
- onDisconnected?: () => void;
26
- /** Cada evento crudo, antes del reductor (analítica, efectos propios). */
27
- onEvent?: (name: string, data: unknown) => void;
28
- /** Cada mensaje que sale (analítica: «primer mensaje»). */
29
- onSend?: (input: SendInput) => void;
30
+ /** Cada evento AG-UI crudo, antes del reductor (analítica, STATE_*, CUSTOM propios). */
31
+ onEvent?: (event: BaseEvent) => void;
32
+ /** Cada run que sale (analítica). */
33
+ onSend?: (input: RunAgentInput) => void;
30
34
  }
31
35
  export interface SendOptions {
32
- resume?: boolean;
33
- resumeTurnId?: string;
34
36
  references?: Reference[];
35
37
  }
36
38
  export interface Pilot {
37
39
  state: PilotState;
40
+ threadId: string;
38
41
  send: (text: string, attachments?: Attachment[], opts?: SendOptions) => Promise<void>;
42
+ /** Detiene el run: corta la conexión (el servidor corta el run). */
39
43
  stop: () => void;
40
- /** Reintenta el último mensaje (quita la respuesta anterior). */
44
+ /** Reintenta el último mensaje. */
41
45
  retry: () => void;
42
- /** Turno PERDIDO (no arrancó): se abandona y se reenvía. */
43
- abandonAndRetry: () => void;
44
- /** «Retomar» un turno cortado por el servidor. */
45
- resume: () => void;
46
- setModel: (value: string) => void;
47
- /**
48
- * Contesta una tarjeta. `via` = cómo la contesta la app (p. ej. su ruta de aprobación con la
49
- * sesión); sin él, `transport.respondPermission`. La decisión queda anotada en la respuesta.
50
- */
51
- respondPermission: (id: string, optionId: string, via?: PermissionHandler) => Promise<PermissionAnswer>;
52
- /** Anota lo que ya contestó la app (sin volver a contestar): la tarjeta sale y queda la decisión. */
53
- recordDecision: (id: string, optionId: string, answer: PermissionAnswer, asked?: PermissionRequest) => void;
54
- /** Una tarjeta que venció sin contestarse: sale de las abiertas como «venció». */
46
+ /** Contesta una tarjeta. Cuando ya están contestadas TODAS las abiertas, sale el `resume`. */
47
+ respondPermission: (id: string, approved: boolean) => void;
48
+ /** Anota la decisión bajo la respuesta y retira la tarjeta (tras su sello). */
49
+ recordDecision: (id: string, status: Decision["status"], asked?: PermissionRequest) => void;
50
+ /** Una tarjeta venció sin contestarse: se anota y su interrupt viaja como `cancelled` en el siguiente run. */
55
51
  expirePermission: (id: string) => void;
56
- /** Un mensaje del agente que llegó fuera de un turno: espera a que cierre el turno vivo. */
57
- appendAgentMessage: (text: string) => void;
58
52
  }
59
- /** Lo que contesta la app al resolver una tarjeta. `resolved: false` = ya no estaba abierta. */
60
- export type PermissionAnswer = {
61
- resolved: boolean;
62
- detail?: string;
63
- } | void;
64
- export type PermissionHandler = (id: string, optionId: string) => Promise<PermissionAnswer> | PermissionAnswer;
53
+ /** El contexto de la app como `context` de AG-UI: `[{description, value}]`, `value` siempre texto. */
54
+ export declare function toAgUiContext(ctx: unknown): RunAgentInput["context"];
65
55
  export declare function usePilot(transport: PilotTransport | null, opts?: UsePilotOptions): Pilot;
66
- /** Un transporte SSE estable por `base` (crearlo en cada render reabriría el stream). */
67
- export declare function useSseTransport(base: string | null | undefined, opts?: SseTransportOptions): PilotTransport | null;
package/dist/styles.css CHANGED
@@ -1,4 +1,4 @@
1
- /* ghostykit — Piloto UI · MIT · https://github.com/blissito/ghostykit */
1
+ /* ghostykit — Ghosty Autopilot · MIT · https://github.com/blissito/ghostykit */
2
2
  /* ── Utilidades (Tailwind v4, encerradas en .piloto) ── */
3
3
  /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
4
4
  .piloto {
@@ -34,7 +34,6 @@
34
34
  --font-weight-semibold: 600;
35
35
  --font-weight-extrabold: 800;
36
36
  --tracking-tight: -0.025em;
37
- --leading-tight: 1.25;
38
37
  --radius-md: calc(0.375 * var(--piloto-rem));
39
38
  --radius-lg: calc(0.5 * var(--piloto-rem));
40
39
  --radius-xl: calc(0.75 * var(--piloto-rem));
@@ -304,9 +303,6 @@
304
303
  .piloto .h-2 {
305
304
  height: calc(var(--spacing) * 2);
306
305
  }
307
- .piloto .h-2\.5 {
308
- height: calc(var(--spacing) * 2.5);
309
- }
310
306
  .piloto .h-3 {
311
307
  height: calc(var(--spacing) * 3);
312
308
  }
@@ -331,9 +327,6 @@
331
327
  .piloto .h-9 {
332
328
  height: calc(var(--spacing) * 9);
333
329
  }
334
- .piloto .h-12 {
335
- height: calc(var(--spacing) * 12);
336
- }
337
330
  .piloto .h-16 {
338
331
  height: calc(var(--spacing) * 16);
339
332
  }
@@ -373,18 +366,12 @@
373
366
  .piloto .min-h-\[24px\] {
374
367
  min-height: 24px;
375
368
  }
376
- .piloto .min-h-\[50vh\] {
377
- min-height: 50vh;
378
- }
379
369
  .piloto .min-h-\[200px\] {
380
370
  min-height: 200px;
381
371
  }
382
372
  .piloto .w-2 {
383
373
  width: calc(var(--spacing) * 2);
384
374
  }
385
- .piloto .w-2\.5 {
386
- width: calc(var(--spacing) * 2.5);
387
- }
388
375
  .piloto .w-3 {
389
376
  width: calc(var(--spacing) * 3);
390
377
  }
@@ -412,9 +399,6 @@
412
399
  .piloto .w-10 {
413
400
  width: calc(var(--spacing) * 10);
414
401
  }
415
- .piloto .w-12 {
416
- width: calc(var(--spacing) * 12);
417
- }
418
402
  .piloto .w-16 {
419
403
  width: calc(var(--spacing) * 16);
420
404
  }
@@ -581,9 +565,6 @@
581
565
  .piloto .gap-6 {
582
566
  gap: calc(var(--spacing) * 6);
583
567
  }
584
- .piloto .gap-8 {
585
- gap: calc(var(--spacing) * 8);
586
- }
587
568
  .piloto .gap-\[2px\] {
588
569
  gap: 2px;
589
570
  }
@@ -769,9 +750,6 @@
769
750
  background-color: color-mix(in oklab, var(--color-background-secondary) 50%, transparent);
770
751
  }
771
752
  }
772
- .piloto .bg-background-success {
773
- background-color: var(--color-background-success);
774
- }
775
753
  .piloto .bg-background\/50 {
776
754
  background-color: var(--color-background);
777
755
  @supports (color: color-mix(in lab, red, red)) {
@@ -808,9 +786,6 @@
808
786
  background-color: color-mix(in oklab, var(--color-black) 60%, transparent);
809
787
  }
810
788
  }
811
- .piloto .bg-border-primary {
812
- background-color: var(--color-border-primary);
813
- }
814
789
  .piloto .bg-brand-500 {
815
790
  background-color: var(--color-brand-500);
816
791
  }
@@ -862,9 +837,6 @@
862
837
  background-color: color-mix(in oklab, var(--color-sidebar) 80%, transparent);
863
838
  }
864
839
  }
865
- .piloto .bg-text-danger {
866
- background-color: var(--color-text-danger);
867
- }
868
840
  .piloto .bg-text-primary {
869
841
  background-color: var(--color-text-primary);
870
842
  }
@@ -1037,10 +1009,6 @@
1037
1009
  --tw-leading: 1;
1038
1010
  line-height: 1;
1039
1011
  }
1040
- .piloto .leading-tight {
1041
- --tw-leading: var(--leading-tight);
1042
- line-height: var(--leading-tight);
1043
- }
1044
1012
  .piloto .font-extrabold {
1045
1013
  --tw-font-weight: var(--font-weight-extrabold);
1046
1014
  font-weight: var(--font-weight-extrabold);
@@ -1190,9 +1158,6 @@
1190
1158
  .piloto .ring-ring-info {
1191
1159
  --tw-ring-color: var(--color-ring-info);
1192
1160
  }
1193
- .piloto .filter {
1194
- filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
1195
- }
1196
1161
  .piloto .backdrop-blur-sm {
1197
1162
  --tw-backdrop-blur: blur(var(--blur-sm));
1198
1163
  -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
@@ -1697,59 +1662,6 @@
1697
1662
  inherits: false;
1698
1663
  initial-value: 0 0 #0000;
1699
1664
  }
1700
- @property --tw-blur {
1701
- syntax: "*";
1702
- inherits: false;
1703
- }
1704
- @property --tw-brightness {
1705
- syntax: "*";
1706
- inherits: false;
1707
- }
1708
- @property --tw-contrast {
1709
- syntax: "*";
1710
- inherits: false;
1711
- }
1712
- @property --tw-grayscale {
1713
- syntax: "*";
1714
- inherits: false;
1715
- }
1716
- @property --tw-hue-rotate {
1717
- syntax: "*";
1718
- inherits: false;
1719
- }
1720
- @property --tw-invert {
1721
- syntax: "*";
1722
- inherits: false;
1723
- }
1724
- @property --tw-opacity {
1725
- syntax: "*";
1726
- inherits: false;
1727
- }
1728
- @property --tw-saturate {
1729
- syntax: "*";
1730
- inherits: false;
1731
- }
1732
- @property --tw-sepia {
1733
- syntax: "*";
1734
- inherits: false;
1735
- }
1736
- @property --tw-drop-shadow {
1737
- syntax: "*";
1738
- inherits: false;
1739
- }
1740
- @property --tw-drop-shadow-color {
1741
- syntax: "*";
1742
- inherits: false;
1743
- }
1744
- @property --tw-drop-shadow-alpha {
1745
- syntax: "<percentage>";
1746
- inherits: false;
1747
- initial-value: 100%;
1748
- }
1749
- @property --tw-drop-shadow-size {
1750
- syntax: "*";
1751
- inherits: false;
1752
- }
1753
1665
  @property --tw-backdrop-blur {
1754
1666
  syntax: "*";
1755
1667
  inherits: false;
@@ -1860,19 +1772,6 @@
1860
1772
  --tw-ring-offset-width: 0px;
1861
1773
  --tw-ring-offset-color: #fff;
1862
1774
  --tw-ring-offset-shadow: 0 0 #0000;
1863
- --tw-blur: initial;
1864
- --tw-brightness: initial;
1865
- --tw-contrast: initial;
1866
- --tw-grayscale: initial;
1867
- --tw-hue-rotate: initial;
1868
- --tw-invert: initial;
1869
- --tw-opacity: initial;
1870
- --tw-saturate: initial;
1871
- --tw-sepia: initial;
1872
- --tw-drop-shadow: initial;
1873
- --tw-drop-shadow-color: initial;
1874
- --tw-drop-shadow-alpha: 100%;
1875
- --tw-drop-shadow-size: initial;
1876
1775
  --tw-backdrop-blur: initial;
1877
1776
  --tw-backdrop-brightness: initial;
1878
1777
  --tw-backdrop-contrast: initial;
@@ -1891,7 +1790,7 @@
1891
1790
 
1892
1791
  /* ── La piel ── */
1893
1792
  /* ─────────────────────────────────────────────────────────────────────────────
1894
- Piloto UI — la piel.
1793
+ Ghosty Autopilot — la piel.
1895
1794
 
1896
1795
  El chat es el de Ghosty Studio (`/c`): mismas piezas, mismas clases, mismos
1897
1796
  valores. Aquí viven (1) las variables `--piloto-*`, cuyos valores de casa son
@@ -1,32 +1,42 @@
1
- import { type PilotTransport } from "./types";
2
- export * from "./types";
3
- export { createPostStreamTransport, readSse, type PostStreamTransportOptions, type SseMessage } from "./postStream";
4
- /** Los eventos con nombre del contrato. Un evento SSE sin `addEventListener` no se despacha nunca. */
5
- export declare const SSE_EVENTS: readonly ["started", "status", "caps", "models", "chunk", "thought", "tool", "artifact", "usage", "title", "done", "error", "warning", "reemplazo", "permission", "permission-resolved", "closed", "page-plan", "section-building", "section-update", "section", "page-ready", "page-error", "page-planning", "page-drop", "review", "page-version", "page-edit", "snapshot", "idle", "interrupted", "capacity"];
6
- /**
7
- * Tope de silencio del cliente, la red de seguridad: pasado esto SIN NINGÚN evento —ni el `status`
8
- * que el servidor manda cada 25 s con turno vivo— la conexión está muerta aunque el navegador no lo
9
- * note. No se da el turno por perdido: se reconecta y el servidor dice la verdad. ≥ el silencio
10
- * máximo del servidor (10 min) para no adelantarse nunca a él si no manda latido.
11
- */
12
- export declare const SILENCE_MAX_MS: number;
13
- /** Con latido anunciado, basta con perder unos cuantos para saber que la conexión murió. */
14
- export declare const MISSED_BEATS = 4;
15
- /** Piso del tope con latido: un latido muy corto no debe reconectar a lo loco. */
16
- export declare const MIN_SILENCE_MS = 90000;
17
- export interface SseTransportOptions {
18
- /** Para mandar cabeceras propias (auth) en los POST. */
1
+ import type { BaseEvent, RunAgentInput } from "@ag-ui/core";
2
+ export interface PilotTransport {
3
+ /**
4
+ * Corre un run: manda `input`, entrega cada evento AG-UI a `onEvent` en orden y se resuelve cuando el
5
+ * servidor cierra el stream. Rechaza con `PilotHttpError` si el servidor dice que no antes de empezar.
6
+ */
7
+ run(input: RunAgentInput, onEvent: (event: BaseEvent) => void, signal?: AbortSignal): Promise<void>;
8
+ }
9
+ /** El servidor rechazó el run antes de empezar (§6 de docs/protocol.md). */
10
+ export declare class PilotHttpError extends Error {
11
+ status: number;
12
+ /** El `error` del cuerpo: `run_active`, `interrupt_pending`, `bad_request`… */
13
+ code?: string;
14
+ /** Segundos de `Retry-After` (429/503). */
15
+ retryAfter?: number;
16
+ constructor(message: string, status: number, code?: string, retryAfter?: number);
17
+ }
18
+ export interface AgUiTransportOptions {
19
+ /** El endpoint del agente: `POST <url>`. */
20
+ url: string;
21
+ /** Cabeceras propias (auth por token). */
22
+ headers?: Record<string, string>;
23
+ /** Default `same-origin`: la cookie de sesión viaja sola. */
24
+ credentials?: RequestCredentials;
19
25
  fetch?: typeof fetch;
20
- /** Cookies en un stream de otro origen (widget embebido). */
21
- withCredentials?: boolean;
22
- /** Para pruebas o entornos sin `EventSource` global. */
23
- EventSource?: typeof EventSource;
24
- /** Eventos extra a escuchar (además de `SSE_EVENTS`). */
25
- events?: string[];
26
- /** Cada cuánto se revisa el silencio. */
27
- checkEveryMs?: number;
28
- /** Reloj inyectable (pruebas). */
29
- now?: () => number;
26
+ /** Reintentos de un 503 (deploy) con el MISMO run. Default 6. */
27
+ retries?: number;
28
+ /** Espera inyectable (pruebas). */
29
+ sleep?: (ms: number) => Promise<void>;
30
30
  }
31
- /** El transporte SSE de Ghosty: `GET ${base}/events` (stream) y POST a `messages|cancel|model|permission`. */
32
- export declare function createSseTransport(base: string, opts?: SseTransportOptions): PilotTransport;
31
+ /** Un evento SSE ya separado: nombre + data crudo. */
32
+ export interface SseMessage {
33
+ event: string;
34
+ data: string;
35
+ }
36
+ /**
37
+ * Lee un stream SSE (`text/event-stream`) de un `fetch`. Los comentarios (`: ping`) se ignoran; un
38
+ * evento puede llegar partido en varios pedazos de red.
39
+ */
40
+ export declare function readSse(body: ReadableStream<Uint8Array>, onMessage: (m: SseMessage) => void): Promise<void>;
41
+ /** El transporte AG-UI sobre HTTP (SSE). */
42
+ export declare function createAgUiTransport(opts: AgUiTransportOptions): PilotTransport;
@@ -1,20 +1,10 @@
1
1
  import {
2
- MIN_SILENCE_MS,
3
- MISSED_BEATS,
4
2
  PilotHttpError,
5
- SILENCE_MAX_MS,
6
- SSE_EVENTS,
7
- createPostStreamTransport,
8
- createSseTransport,
3
+ createAgUiTransport,
9
4
  readSse
10
- } from "../chunks/chunk-XZHX2NZT.js";
5
+ } from "../chunks/chunk-DXFWACUL.js";
11
6
  export {
12
- MIN_SILENCE_MS,
13
- MISSED_BEATS,
14
7
  PilotHttpError,
15
- SILENCE_MAX_MS,
16
- SSE_EVENTS,
17
- createPostStreamTransport,
18
- createSseTransport,
8
+ createAgUiTransport,
19
9
  readSse
20
10
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ghostykit",
3
- "version": "0.3.2",
4
- "description": "Piloto UI — the in-app copilot chat from Ghosty Studio: streaming, agent steps, attachments, voice, reconnection and human approval cards. Pure event reducer + SSE transport + React components.",
3
+ "version": "0.4.0",
4
+ "description": "Ghosty Autopilot \u2014 the autopilot chat for your React app, on AG-UI: works with LangGraph, Mastra, CrewAI or any AG-UI agent. Streaming text, agent steps, human approval cards (interrupt/resume), attachments and voice.",
5
5
  "type": "module",
6
6
  "main": "./dist/core/index.js",
7
7
  "types": "./dist/core/index.d.ts",
@@ -59,6 +59,7 @@
59
59
  "devDependencies": {
60
60
  "@ghostystudio/pointer": "^0.4.0",
61
61
  "@tailwindcss/cli": "^4.1.0",
62
+ "@types/node": "^22.20.5",
62
63
  "@types/react": "^19.0.0",
63
64
  "@types/react-dom": "^19.0.0",
64
65
  "esbuild": "^0.25.0",
@@ -74,15 +75,18 @@
74
75
  "vitest": "^3.2.0"
75
76
  },
76
77
  "keywords": [
77
- "ai",
78
+ "acp",
79
+ "ag-ui",
78
80
  "agent",
79
- "copilot",
81
+ "ai",
82
+ "autopilot",
80
83
  "chat",
81
- "react",
82
- "sse",
83
- "acp",
84
+ "copilot",
85
+ "ghosty",
84
86
  "human-in-the-loop",
85
- "ghosty"
87
+ "langgraph",
88
+ "react",
89
+ "sse"
86
90
  ],
87
91
  "license": "MIT",
88
92
  "repository": {
@@ -90,5 +94,8 @@
90
94
  "url": "git+https://github.com/blissito/ghostykit.git",
91
95
  "directory": "packages/ghostykit"
92
96
  },
93
- "homepage": "https://github.com/blissito/ghostykit#readme"
97
+ "homepage": "https://github.com/blissito/ghostykit#readme",
98
+ "dependencies": {
99
+ "@ag-ui/core": "^1.0.3"
100
+ }
94
101
  }