@blade-hq/agent-client 1.2.0-beta.1 → 1.2.1-alpha.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/dist/index.js CHANGED
@@ -892,6 +892,11 @@ function toolStatusFromResult(result) {
892
892
  }
893
893
 
894
894
  // src/shared/projection/builder.ts
895
+ function isConversationTurn(turn) {
896
+ return (turn.role === "user" || turn.role === "assistant") && (turn.kind ?? "message") === "message" && !turn.blocks.some(
897
+ (block) => block.type === "mode_change" || block.type === "plan_status" || block.type === "ask_user_answer"
898
+ );
899
+ }
895
900
  var ClientProjectionBuilder = class {
896
901
  activeTurns = /* @__PURE__ */ new Map();
897
902
  lastTurnIds = /* @__PURE__ */ new Map();
@@ -948,6 +953,8 @@ var ClientProjectionBuilder = class {
948
953
  return this.onAskUserAnswer(loopId, payload);
949
954
  case "user:message":
950
955
  return this.onUserMessage(loopId, payload);
956
+ case "session:post_chat_followup":
957
+ return this.onPostChatFollowup(payload);
951
958
  }
952
959
  if (event.type.startsWith("compaction:"))
953
960
  return this.onCompaction(event.type, loopId, payload);
@@ -1005,6 +1012,18 @@ var ClientProjectionBuilder = class {
1005
1012
  this.seq = maxSeq;
1006
1013
  }
1007
1014
  }
1015
+ _seedTurns(turns) {
1016
+ const latestTurns = /* @__PURE__ */ new Map();
1017
+ for (const turn of turns) {
1018
+ this.seedSequence(turn.sequence);
1019
+ if (!isConversationTurn(turn)) continue;
1020
+ const current = latestTurns.get(turn.loop_id);
1021
+ if (!current || turn.sequence >= current.sequence) {
1022
+ latestTurns.set(turn.loop_id, turn);
1023
+ }
1024
+ }
1025
+ this.latestTurns = latestTurns;
1026
+ }
1008
1027
  // --- Event handlers ---
1009
1028
  onMemoryInject(loopId, payload) {
1010
1029
  const refs = payload.memory_refs;
@@ -1193,6 +1212,27 @@ var ClientProjectionBuilder = class {
1193
1212
  usage: null,
1194
1213
  duration_ms: 0
1195
1214
  };
1215
+ this.latestTurns.set("root", turn);
1216
+ return [{ kind: "upsert", turn }];
1217
+ }
1218
+ onPostChatFollowup(payload) {
1219
+ const assistantEntryId = String(payload.assistant_entry_id ?? "");
1220
+ const latest = this.latestTurns.get("root");
1221
+ if (!latest || latest.role !== "assistant" || latest.turn_id !== assistantEntryId) {
1222
+ return null;
1223
+ }
1224
+ const suggestions = payload.suggestions;
1225
+ const postChatFollowup = Array.isArray(suggestions) && suggestions.length === 3 && suggestions.every((value) => typeof value === "string") ? {
1226
+ assistant_entry_id: assistantEntryId,
1227
+ recaption: String(payload.recaption ?? ""),
1228
+ suggestions
1229
+ } : null;
1230
+ if (!postChatFollowup) return null;
1231
+ const turn = {
1232
+ ...latest,
1233
+ post_chat_followup: postChatFollowup
1234
+ };
1235
+ this.latestTurns.set("root", turn);
1196
1236
  return [{ kind: "upsert", turn }];
1197
1237
  }
1198
1238
  // --- Delta / streaming events ---
@@ -1545,11 +1585,24 @@ function projectHistory(entries) {
1545
1585
  const toolOwners = /* @__PURE__ */ new Map();
1546
1586
  const latestAssistantByLoop = /* @__PURE__ */ new Map();
1547
1587
  const pendingChildPauses = /* @__PURE__ */ new Map();
1588
+ let latestRootMessage = null;
1548
1589
  let sequence = 0;
1549
1590
  for (const entry of entries) {
1550
1591
  const kind = String(entry.kind ?? "");
1551
1592
  const loopId = String(entry.loop_name ?? "root");
1552
1593
  const id = String(entry.id ?? `history-${sequence + 1}`);
1594
+ if (kind === "post_chat_followup" && isRecord3(entry.data)) {
1595
+ const assistantEntryId = String(entry.data.assistant_entry_id ?? "");
1596
+ const suggestions = entry.data.suggestions;
1597
+ if (latestRootMessage?.role === "assistant" && latestRootMessage.turn_id === assistantEntryId && Array.isArray(suggestions) && suggestions.length === 3 && suggestions.every((value) => typeof value === "string")) {
1598
+ latestRootMessage.post_chat_followup = {
1599
+ assistant_entry_id: assistantEntryId,
1600
+ recaption: String(entry.data.recaption ?? ""),
1601
+ suggestions
1602
+ };
1603
+ }
1604
+ continue;
1605
+ }
1553
1606
  if (kind === "message" && isRecord3(entry.message)) {
1554
1607
  const message = entry.message;
1555
1608
  const role = String(message.role ?? "");
@@ -1586,6 +1639,9 @@ function projectHistory(entries) {
1586
1639
  duration_ms: numberOrZero(message._duration_ms),
1587
1640
  started_at: typeof entry.timestamp === "string" ? entry.timestamp : void 0
1588
1641
  };
1642
+ if (loopId === "root" && (role === "user" || role === "assistant")) {
1643
+ latestRootMessage = turn;
1644
+ }
1589
1645
  turns.push(turn);
1590
1646
  if (role === "assistant") latestAssistantByLoop.set(loopId, turn);
1591
1647
  for (const toolCall of toolCalls) toolOwners.set(toolCall.id, turn);
@@ -3237,11 +3293,14 @@ var AgentSession = class _AgentSession {
3237
3293
  _handleTurnEvents(events) {
3238
3294
  if (!events.length) return;
3239
3295
  const terminalChatEndStatus = extractTerminalChatEndStatus(events);
3240
- if (!terminalChatEndStatus) {
3296
+ const followupOnly = events.every(
3297
+ (event) => event.type === "session:post_chat_followup"
3298
+ );
3299
+ if (!terminalChatEndStatus && !followupOnly) {
3241
3300
  this.markRunningIfIdle();
3242
3301
  }
3243
3302
  if (this.state.turns.length) {
3244
- this.projectionBuilder.seedSequence(Math.max(...this.state.turns.map((t) => t.sequence)));
3303
+ this.projectionBuilder._seedTurns(this.state.turns);
3245
3304
  }
3246
3305
  const updates = this.projectionBuilder.processBatch(events);
3247
3306
  for (const update of updates) {
@@ -3894,7 +3953,7 @@ function resolveAuthToken(options) {
3894
3953
 
3895
3954
  // src/version.ts
3896
3955
  var SDK_NAME = "agent-client";
3897
- var SDK_VERSION = true ? "1.2.0-beta.1" : "1.1.1";
3956
+ var SDK_VERSION = true ? "1.2.1-alpha.1" : "1.1.1";
3898
3957
 
3899
3958
  // src/socket.ts
3900
3959
  function withSdkIdentity(auth) {