ghostykit 0.6.1 → 0.6.2
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.
|
@@ -408,6 +408,8 @@ function finish(s0, e, now, failed = false) {
|
|
|
408
408
|
{ used: 0, size: 0, cost: 0 }
|
|
409
409
|
) : null;
|
|
410
410
|
const usage = tokens || costUsd !== void 0 ? { ...tokens ?? { used: 0, size: 0, cost: 0 }, ...costUsd !== void 0 ? { cost: costUsd } : {} } : null;
|
|
411
|
+
const cut = e.metadata?.interrupted;
|
|
412
|
+
s = { ...s, cutRun: cut && typeof cut.runId === "string" ? { runId: cut.runId, ...typeof cut.reason === "string" && cut.reason ? { reason: cut.reason } : {} } : null };
|
|
411
413
|
const t0 = s.turnStartedAt;
|
|
412
414
|
const seconds = t0 ? Math.max(1, Math.round((now - t0) / 1e3)) : void 0;
|
|
413
415
|
const turns = [...s.turns];
|
|
@@ -427,7 +429,7 @@ function finish(s0, e, now, failed = false) {
|
|
|
427
429
|
}
|
|
428
430
|
function beginSend(prev, text, attachments = [], now = Date.now()) {
|
|
429
431
|
const turns = text || attachments.length ? [...prev.turns, { role: "user", text, ...attachments.length ? { attachments } : {} }] : prev.turns;
|
|
430
|
-
return { ...prev, turns, busy: true, error: null, notice: null, turnStartedAt: now, effects: [{ type: "turn-start" }] };
|
|
432
|
+
return { ...prev, turns, busy: true, error: null, notice: null, cutRun: null, turnStartedAt: now, effects: [{ type: "turn-start" }] };
|
|
431
433
|
}
|
|
432
434
|
function beginSteer(prev, text) {
|
|
433
435
|
return { ...prev, turns: [...prev.turns, { role: "user", text }], notice: null, openText: null, effects: [] };
|
package/dist/core/index.js
CHANGED
package/dist/core/types.d.ts
CHANGED
|
@@ -163,6 +163,14 @@ export interface PilotState {
|
|
|
163
163
|
olderCount: number;
|
|
164
164
|
/** El `ghosty.history` que acompaña al snapshot que viene. */
|
|
165
165
|
historyNext?: HistoryPage | null;
|
|
166
|
+
/**
|
|
167
|
+
* El último run se cortó del lado del servidor (deploy, caja caída): `RUN_FINISHED.metadata.interrupted`.
|
|
168
|
+
* `reason` ya viene en palabras de persona. Se ofrece «Continuar».
|
|
169
|
+
*/
|
|
170
|
+
cutRun?: {
|
|
171
|
+
runId: string;
|
|
172
|
+
reason?: string;
|
|
173
|
+
} | null;
|
|
166
174
|
/** Mensajes en espera de que termine el run vivo (steer rechazado). */
|
|
167
175
|
queued: QueuedMessage[];
|
|
168
176
|
/** Lo que estaba en espera cuando la persona detuvo: regresa a la caja (`n` cambia en cada vez). */
|
package/dist/react/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
toPermission,
|
|
32
32
|
toolName,
|
|
33
33
|
toolNames
|
|
34
|
-
} from "../chunks/chunk-
|
|
34
|
+
} from "../chunks/chunk-ZJ34IR2Z.js";
|
|
35
35
|
import {
|
|
36
36
|
PilotHttpError,
|
|
37
37
|
createAgUiTransport,
|
|
@@ -894,6 +894,8 @@ var STRINGS_ES = {
|
|
|
894
894
|
steps: { waking: "Despertando al agente\u2026", session: "Preparando la sesi\xF3n\u2026", compacting: "Resumiendo la conversaci\xF3n\u2026" },
|
|
895
895
|
loadOlder: "Cargar mensajes anteriores",
|
|
896
896
|
loadingOlder: "Cargando\u2026",
|
|
897
|
+
continueRun: "Continuar",
|
|
898
|
+
runCut: "La respuesta se cort\xF3 antes de terminar.",
|
|
897
899
|
queued: "Se manda cuando termine",
|
|
898
900
|
subagentsWorking: (n) => n === 1 ? "1 agente trabajando" : `${n} agentes trabajando`,
|
|
899
901
|
subagentsDone: (n) => n === 1 ? "1 agente termin\xF3" : `${n} agentes terminaron`,
|
|
@@ -967,6 +969,8 @@ var STRINGS_EN = {
|
|
|
967
969
|
steps: { waking: "Waking the agent\u2026", session: "Starting the session\u2026", compacting: "Compacting the conversation\u2026" },
|
|
968
970
|
loadOlder: "Load earlier messages",
|
|
969
971
|
loadingOlder: "Loading\u2026",
|
|
972
|
+
continueRun: "Continue",
|
|
973
|
+
runCut: "The answer was cut off before it finished.",
|
|
970
974
|
queued: "Sends when this finishes",
|
|
971
975
|
subagentsWorking: (n) => n === 1 ? "1 agent working" : `${n} agents working`,
|
|
972
976
|
subagentsDone: (n) => n === 1 ? "1 agent finished" : `${n} agents finished`,
|
|
@@ -2386,7 +2390,7 @@ function usePilot(transport, opts = {}) {
|
|
|
2386
2390
|
ctrl.current = c;
|
|
2387
2391
|
const steering = typeof input.forwardedProps?.steer === "string";
|
|
2388
2392
|
const userMsg = input.messages[0];
|
|
2389
|
-
if (!steering && (input.messages.length || input.resume?.length)) liveRun.current = input.runId;
|
|
2393
|
+
if (!steering && (input.messages.length || input.resume?.length || input.forwardedProps?.continueRun)) liveRun.current = input.runId;
|
|
2390
2394
|
optsRef.current.onSend?.(input);
|
|
2391
2395
|
let ended = false;
|
|
2392
2396
|
try {
|
|
@@ -2406,6 +2410,11 @@ function usePilot(transport, opts = {}) {
|
|
|
2406
2410
|
} catch (err) {
|
|
2407
2411
|
if (c.signal.aborted) return;
|
|
2408
2412
|
const code = err instanceof PilotHttpError ? err.code : void 0;
|
|
2413
|
+
if (code === "nothing_to_continue") {
|
|
2414
|
+
liveRun.current = null;
|
|
2415
|
+
commit({ ...ref.current, busy: false, turnStartedAt: 0, cutRun: null, effects: [] });
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2409
2418
|
if ((code === "run_active" || code === "interrupt_pending") && !reopening) {
|
|
2410
2419
|
if (userMsg) {
|
|
2411
2420
|
const { text, attachments } = fromUserMessage(userMsg.content);
|
|
@@ -2571,10 +2580,16 @@ function usePilot(transport, opts = {}) {
|
|
|
2571
2580
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2572
2581
|
[commit, runNow]
|
|
2573
2582
|
);
|
|
2583
|
+
const continueRun = useCallback2(async () => {
|
|
2584
|
+
const cut = ref.current.cutRun;
|
|
2585
|
+
if (!cut || ref.current.busy || !transportRef.current) return;
|
|
2586
|
+
commit(beginSend(ref.current, "", []));
|
|
2587
|
+
await runNow({ messages: [], forwardedProps: { continueRun: cut.runId } });
|
|
2588
|
+
}, [commit, runNow]);
|
|
2574
2589
|
const refresh = useCallback2(() => runNow({ messages: [] }, true), [runNow]);
|
|
2575
2590
|
const canSteer = Boolean(transport) && (opts.steer ?? state.agentState.caps?.steer === true);
|
|
2576
2591
|
const subagents = useMemo3(() => subagentsOf(state.agentState), [state.agentState]);
|
|
2577
|
-
return { state, threadId, send, stop, retry, respondPermission, recordDecision, expirePermission, canSteer, loadOlder, loadingOlder, subagents, stopSubagent, refresh };
|
|
2592
|
+
return { state, threadId, send, stop, retry, respondPermission, recordDecision, expirePermission, canSteer, loadOlder, loadingOlder, subagents, stopSubagent, refresh, continueRun };
|
|
2578
2593
|
}
|
|
2579
2594
|
|
|
2580
2595
|
// src/react/Piloto.tsx
|
|
@@ -2893,6 +2908,19 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2893
2908
|
children: /* @__PURE__ */ jsx10(ArrowDown, { className: "h-4 w-4" })
|
|
2894
2909
|
}
|
|
2895
2910
|
),
|
|
2911
|
+
state.cutRun && !busy && // El servidor cortó la respuesta (deploy, caja caída): la persona decide si sigue.
|
|
2912
|
+
/* @__PURE__ */ jsxs8("div", { "data-cut-run": true, role: "status", className: "mb-2 flex items-center gap-3 rounded-2xl border border-border-primary bg-background-secondary px-3 py-2 text-sm text-text-secondary", children: [
|
|
2913
|
+
/* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1", children: state.cutRun.reason ?? t.runCut }),
|
|
2914
|
+
/* @__PURE__ */ jsx10(
|
|
2915
|
+
"button",
|
|
2916
|
+
{
|
|
2917
|
+
type: "button",
|
|
2918
|
+
onClick: () => void pilot.continueRun(),
|
|
2919
|
+
className: "shrink-0 rounded-full bg-brand-500 px-3 py-1 text-sm font-medium text-white transition hover:bg-brand-600",
|
|
2920
|
+
children: t.continueRun
|
|
2921
|
+
}
|
|
2922
|
+
)
|
|
2923
|
+
] }),
|
|
2896
2924
|
aboveComposer,
|
|
2897
2925
|
composer
|
|
2898
2926
|
] })
|
package/dist/react/strings.d.ts
CHANGED
|
@@ -58,6 +58,10 @@ export interface PilotStrings {
|
|
|
58
58
|
steps: Record<string, string>;
|
|
59
59
|
loadOlder: string;
|
|
60
60
|
loadingOlder: string;
|
|
61
|
+
/** El botón de la franja de un run cortado por el servidor (mismo rótulo en iOS y Android). */
|
|
62
|
+
continueRun: string;
|
|
63
|
+
/** La franja, si el servidor no dio razón. */
|
|
64
|
+
runCut: string;
|
|
61
65
|
/** Bajo un mensaje que espera a que termine el run vivo. */
|
|
62
66
|
queued: string;
|
|
63
67
|
/** «2 agentes trabajando». */
|
package/dist/react/usePilot.d.ts
CHANGED
|
@@ -82,6 +82,8 @@ export interface Pilot {
|
|
|
82
82
|
* por fuera que algo cambió (p. ej. el bus `/me/events` avisa que un subagente terminó).
|
|
83
83
|
*/
|
|
84
84
|
refresh: () => Promise<void>;
|
|
85
|
+
/** Continúa el run que el servidor cortó (`state.cutRun`): `forwardedProps.continueRun`. */
|
|
86
|
+
continueRun: () => Promise<void>;
|
|
85
87
|
}
|
|
86
88
|
/** El contexto de la app como `context` de AG-UI: `[{description, value}]`, `value` siempre texto. */
|
|
87
89
|
export declare function toAgUiContext(ctx: unknown): RunAgentInput["context"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghostykit",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
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",
|