ghostykit 0.6.0 → 0.6.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.
@@ -184,6 +184,26 @@ function attachmentsOf(content) {
184
184
  }
185
185
  return out.length ? out : void 0;
186
186
  }
187
+ function toolLabel(t, v) {
188
+ const x = v ?? {};
189
+ if (typeof x.toolCallId !== "string") return;
190
+ const str = (y) => typeof y === "string" && y ? y : void 0;
191
+ const patch = {};
192
+ if (str(x.title)) patch.label = str(x.title);
193
+ if (str(x.kind)) patch.kind = str(x.kind);
194
+ if (str(x.path)) patch.path = str(x.path);
195
+ if (str(x.detail)) patch.detail = str(x.detail);
196
+ t.tools = (t.tools ?? []).map((y) => y.id === x.toolCallId ? { ...y, ...patch } : y);
197
+ }
198
+ function applyStoredCustom(t, m) {
199
+ const custom = m.metadata?.custom;
200
+ if (!Array.isArray(custom)) return;
201
+ for (const c of custom) {
202
+ if (!c || typeof c.name !== "string") continue;
203
+ if (c.name === "ghosty.tool") toolLabel(t, c.value);
204
+ else if (!NOT_IN_TURN.has(c.name)) t.custom = [...t.custom ?? [], c];
205
+ }
206
+ }
187
207
  function messagesToTurns(messages) {
188
208
  const turns = [];
189
209
  let cur = null;
@@ -201,8 +221,6 @@ function messagesToTurns(messages) {
201
221
  } else if (m.role === "assistant") {
202
222
  const t = assistant();
203
223
  if (!t.id && m.id) t.id = m.id;
204
- const custom = m.metadata?.custom;
205
- if (Array.isArray(custom) && custom.length) t.custom = [...t.custom ?? [], ...custom.filter((c) => c && typeof c.name === "string")];
206
224
  const text = m.content ?? "";
207
225
  if (text) t.text = t.text ? `${t.text}
208
226
 
@@ -211,10 +229,12 @@ ${text}` : text;
211
229
  t.tools = [...t.tools ?? [], { id: c.id, title: c.function.name, status: "pending", args: c.function.arguments, detail: argsDetail(c.function.arguments) }];
212
230
  if (t.text.trim() && t.cuts?.[t.cuts.length - 1] !== t.text.length) t.cuts = [...t.cuts ?? [], t.text.length];
213
231
  }
232
+ applyStoredCustom(t, m);
214
233
  } else if (m.role === "tool") {
215
234
  const t = assistant(m.id);
216
235
  const failed = Boolean(m.error);
217
236
  t.tools = (t.tools ?? []).map((x) => x.id === m.toolCallId ? { ...x, status: failed ? "failed" : "completed" } : x);
237
+ applyStoredCustom(t, m);
218
238
  } else if (m.role === "reasoning") {
219
239
  const t = assistant(m.id);
220
240
  t.thought = (t.thought ?? "") + textOf(m.content);
@@ -366,7 +386,8 @@ ${content}` : content };
366
386
  function toHistory(v) {
367
387
  if (!v || typeof v !== "object") return null;
368
388
  const h = v;
369
- return { hasMoreBefore: h.hasMoreBefore === true, ...typeof h.before === "string" ? { before: h.before } : {} };
389
+ const before = typeof h.before === "string" || typeof h.before === "number" ? String(h.before) : void 0;
390
+ return { hasMoreBefore: h.hasMoreBefore === true, ...before !== void 0 ? { before } : {} };
370
391
  }
371
392
  function finish(s0, e, now, failed = false) {
372
393
  let s = { ...s0, busy: false, step: null, openText: null };
@@ -439,7 +460,33 @@ function markSubagent(prev, taskId, status) {
439
460
  function prependHistory(prev, messages, page) {
440
461
  const have = new Set(prev.turns.map((t) => t.id).filter(Boolean));
441
462
  const older = messagesToTurns(messages).filter((t) => !t.id || !have.has(t.id));
442
- return { ...prev, turns: [...older, ...prev.turns], olderCount: prev.olderCount + older.length, history: page, effects: [] };
463
+ let turns = prev.turns;
464
+ const tail = older[older.length - 1];
465
+ const head = turns[0];
466
+ if (tail?.role === "assistant" && head?.role === "assistant") {
467
+ older[older.length - 1] = joinTurns(tail, head);
468
+ turns = turns.slice(1);
469
+ }
470
+ const olderCount = Math.max(0, prev.olderCount + older.length - (turns === prev.turns ? 0 : 1));
471
+ return { ...prev, turns: [...older, ...turns], olderCount, history: page ? { ...page, ...page.before !== void 0 ? { before: String(page.before) } : {} } : page, effects: [] };
472
+ }
473
+ function cutsOf(a, b, shift) {
474
+ const bridge = a.text.trim() && b.tools?.length && !b.cuts?.length ? [a.text.length] : [];
475
+ const cuts = [...a.cuts ?? [], ...bridge, ...(b.cuts ?? []).map((c) => c + shift)];
476
+ return cuts.length ? { cuts } : {};
477
+ }
478
+ function joinTurns(a, b) {
479
+ const sep = a.text && b.text ? "\n\n" : "";
480
+ const shift = a.text.length + sep.length;
481
+ return {
482
+ ...b,
483
+ ...a.id ? { id: a.id } : {},
484
+ text: a.text + sep + b.text,
485
+ ...a.tools || b.tools ? { tools: [...a.tools ?? [], ...b.tools ?? []] } : {},
486
+ ...cutsOf(a, b, shift),
487
+ ...a.custom || b.custom ? { custom: [...a.custom ?? [], ...b.custom ?? []] } : {},
488
+ ...a.thought || b.thought ? { thought: (a.thought ?? "") + (b.thought ?? "") } : {}
489
+ };
443
490
  }
444
491
  function sendFailed(prev, message) {
445
492
  return { ...prev, busy: false, turnStartedAt: 0, error: message, effects: [] };
@@ -31,7 +31,7 @@ import {
31
31
  toPermission,
32
32
  toolName,
33
33
  toolNames
34
- } from "../chunks/chunk-4XKQ6XAJ.js";
34
+ } from "../chunks/chunk-T5PZC5NA.js";
35
35
  import {
36
36
  applyReferences,
37
37
  cleanUserText,
@@ -31,7 +31,7 @@ import {
31
31
  toPermission,
32
32
  toolName,
33
33
  toolNames
34
- } from "../chunks/chunk-4XKQ6XAJ.js";
34
+ } from "../chunks/chunk-T5PZC5NA.js";
35
35
  import {
36
36
  PilotHttpError,
37
37
  createAgUiTransport,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghostykit",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
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",