@adhdev/daemon-core 0.8.63 → 0.8.64

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.mjs CHANGED
@@ -454,19 +454,75 @@ var init_logger = __esm({
454
454
  });
455
455
 
456
456
  // src/providers/chat-message-normalization.ts
457
+ function canonicalizeKindHint(value) {
458
+ return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
459
+ }
460
+ function resolveBuiltinOrAliasKind(kind) {
461
+ if (typeof kind !== "string") return null;
462
+ const normalizedKind = canonicalizeKindHint(kind);
463
+ if (!normalizedKind) return null;
464
+ if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
465
+ return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
466
+ }
467
+ function inferHintKind(value) {
468
+ const direct = resolveBuiltinOrAliasKind(value);
469
+ if (direct) return direct;
470
+ if (typeof value !== "string") return null;
471
+ const normalized = canonicalizeKindHint(value);
472
+ if (!normalized) return null;
473
+ if (/thought|thinking|reasoning/.test(normalized)) return "thought";
474
+ if (/tool/.test(normalized)) return "tool";
475
+ if (/terminal|command|shell|console/.test(normalized)) return "terminal";
476
+ return null;
477
+ }
478
+ function inferKindFromToolCalls(message) {
479
+ const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
480
+ if (toolCalls.length === 0) return null;
481
+ if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
482
+ if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
483
+ if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
484
+ return "terminal";
485
+ }
486
+ return "tool";
487
+ }
488
+ function inferMissingChatMessageKind(message) {
489
+ const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
490
+ if (role === "system") return "system";
491
+ const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
492
+ const hintCandidates = [
493
+ message?._sub,
494
+ message?._type,
495
+ meta?.label,
496
+ typeof message?.senderName === "string" ? message.senderName : void 0
497
+ ];
498
+ for (const candidate of hintCandidates) {
499
+ const inferred = inferHintKind(candidate);
500
+ if (inferred) return inferred;
501
+ }
502
+ const inferredFromToolCalls = inferKindFromToolCalls(message);
503
+ if (inferredFromToolCalls) return inferredFromToolCalls;
504
+ return null;
505
+ }
457
506
  function isBuiltinChatMessageKind(kind) {
458
- return typeof kind === "string" && KNOWN_CHAT_MESSAGE_KINDS.has(kind.trim().toLowerCase());
507
+ return resolveBuiltinOrAliasKind(kind) !== null;
459
508
  }
460
509
  function normalizeChatMessageKind(kind, role) {
461
- const normalizedKind = typeof kind === "string" ? kind.trim().toLowerCase() : "";
462
- if (normalizedKind && KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
510
+ const resolvedKind = resolveBuiltinOrAliasKind(kind);
511
+ if (resolvedKind) return resolvedKind;
463
512
  const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
464
513
  return normalizedRole === "system" ? "system" : "standard";
465
514
  }
515
+ function resolveChatMessageKind(message) {
516
+ const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
517
+ if (explicitKind) return explicitKind;
518
+ const inferredKind = inferMissingChatMessageKind(message);
519
+ if (inferredKind) return inferredKind;
520
+ return normalizeChatMessageKind(message?.kind, message?.role);
521
+ }
466
522
  function buildChatMessage(message) {
467
523
  return {
468
524
  ...message,
469
- kind: normalizeChatMessageKind(message?.kind, message?.role)
525
+ kind: resolveChatMessageKind(message)
470
526
  };
471
527
  }
472
528
  function buildSystemChatMessage(message) {
@@ -489,6 +545,24 @@ function buildAssistantChatMessage(message) {
489
545
  kind: message?.kind || "standard"
490
546
  });
491
547
  }
548
+ function buildThoughtChatMessage(message) {
549
+ return buildAssistantChatMessage({
550
+ ...message,
551
+ kind: message?.kind || "thought"
552
+ });
553
+ }
554
+ function buildToolChatMessage(message) {
555
+ return buildAssistantChatMessage({
556
+ ...message,
557
+ kind: message?.kind || "tool"
558
+ });
559
+ }
560
+ function buildTerminalChatMessage(message) {
561
+ return buildAssistantChatMessage({
562
+ ...message,
563
+ kind: message?.kind || "terminal"
564
+ });
565
+ }
492
566
  function buildUserChatMessage(message) {
493
567
  return buildChatMessage({
494
568
  ...message,
@@ -502,12 +576,30 @@ function normalizeChatMessage(message) {
502
576
  function normalizeChatMessages(messages) {
503
577
  return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
504
578
  }
505
- var BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS;
579
+ var BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES;
506
580
  var init_chat_message_normalization = __esm({
507
581
  "src/providers/chat-message-normalization.ts"() {
508
582
  "use strict";
509
583
  BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
510
584
  KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
585
+ CHAT_MESSAGE_KIND_ALIASES = {
586
+ text: "standard",
587
+ message: "standard",
588
+ assistant: "standard",
589
+ thinking: "thought",
590
+ think: "thought",
591
+ reasoning: "thought",
592
+ reason: "thought",
593
+ toolcall: "tool",
594
+ tool_call: "tool",
595
+ tooluse: "tool",
596
+ tool_use: "tool",
597
+ action: "tool",
598
+ command: "terminal",
599
+ cmd: "terminal",
600
+ shell: "terminal",
601
+ console: "terminal"
602
+ };
511
603
  }
512
604
  });
513
605
 
@@ -3775,6 +3867,45 @@ function getHostMemorySnapshot() {
3775
3867
  return { totalMem, freeMem, availableMem };
3776
3868
  }
3777
3869
 
3870
+ // src/status/chat-tail-hot-sessions.ts
3871
+ var DEFAULT_ACTIVE_CHAT_POLL_STATUSES = /* @__PURE__ */ new Set([
3872
+ "generating",
3873
+ "waiting_approval",
3874
+ "starting"
3875
+ ]);
3876
+ var DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS = 8e3;
3877
+ function parseMessageTimestamp(value) {
3878
+ if (typeof value === "number" && Number.isFinite(value)) return value;
3879
+ if (typeof value === "string") {
3880
+ const parsed = Date.parse(value);
3881
+ if (Number.isFinite(parsed)) return parsed;
3882
+ }
3883
+ return 0;
3884
+ }
3885
+ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessionIds, options = {}) {
3886
+ const now = options.now ?? Date.now();
3887
+ const recentMessageGraceMs = Math.max(
3888
+ 0,
3889
+ Number.isFinite(options.recentMessageGraceMs) ? Number(options.recentMessageGraceMs) : DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS
3890
+ );
3891
+ const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
3892
+ const active = /* @__PURE__ */ new Set();
3893
+ for (const session of sessions) {
3894
+ const sessionId = typeof session?.id === "string" ? session.id : "";
3895
+ if (!sessionId) continue;
3896
+ const status = String(session?.status || "").toLowerCase();
3897
+ const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
3898
+ const recentlyUpdated = lastMessageAt > 0 && now - lastMessageAt <= recentMessageGraceMs;
3899
+ if (activeStatuses.has(status) || recentlyUpdated) {
3900
+ active.add(sessionId);
3901
+ }
3902
+ }
3903
+ const finalizing = new Set(
3904
+ Array.from(previousHotSessionIds).filter((sessionId) => !active.has(sessionId))
3905
+ );
3906
+ return { active, finalizing };
3907
+ }
3908
+
3778
3909
  // src/cdp/manager.ts
3779
3910
  init_logger();
3780
3911
  import WebSocket from "ws";
@@ -6832,11 +6963,13 @@ var IdeProviderInstance = class {
6832
6963
  if (pm.receivedAt) prevByHash.set(h, pm.receivedAt);
6833
6964
  }
6834
6965
  const now = Date.now();
6835
- const messages = chat.messages || [];
6836
- for (const msg of messages) {
6966
+ const rawMessages = chat.messages || [];
6967
+ for (const msg of rawMessages) {
6837
6968
  const h = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
6838
6969
  msg.receivedAt = prevByHash.get(h) || now;
6839
6970
  }
6971
+ chat.messages = normalizeChatMessages(rawMessages);
6972
+ const messages = chat.messages || [];
6840
6973
  if (messages.length > 0) {
6841
6974
  const hiddenKinds = /* @__PURE__ */ new Set();
6842
6975
  if (this.settings.showThinking === false) hiddenKinds.add("thought");
@@ -11431,6 +11564,7 @@ var AcpProviderInstance = class {
11431
11564
  activeToolCalls = [];
11432
11565
  stopReason = null;
11433
11566
  partialContent = "";
11567
+ partialThoughtContent = "";
11434
11568
  /** Rich content blocks accumulated during streaming */
11435
11569
  partialBlocks = [];
11436
11570
  /** Tool calls collected during current turn */
@@ -11476,6 +11610,10 @@ var AcpProviderInstance = class {
11476
11610
  content
11477
11611
  });
11478
11612
  }));
11613
+ if (this.currentStatus === "generating") {
11614
+ const partialThoughtMessage = this.buildPartialThoughtMessage(Date.now());
11615
+ if (partialThoughtMessage) recentMessages.push(partialThoughtMessage);
11616
+ }
11479
11617
  if (this.currentStatus === "generating" && (this.partialContent || this.partialBlocks.length > 0)) {
11480
11618
  const blocks = this.buildPartialBlocks();
11481
11619
  if (blocks.length > 0) {
@@ -12034,6 +12172,7 @@ var AcpProviderInstance = class {
12034
12172
  }));
12035
12173
  this.currentStatus = "generating";
12036
12174
  this.partialContent = "";
12175
+ this.partialThoughtContent = "";
12037
12176
  this.partialBlocks = [];
12038
12177
  this.turnToolCalls = [];
12039
12178
  this.detectStatusTransition();
@@ -12116,7 +12255,14 @@ var AcpProviderInstance = class {
12116
12255
  this.currentStatus = "generating";
12117
12256
  break;
12118
12257
  }
12119
- case "agent_thought_chunk":
12258
+ case "agent_thought_chunk": {
12259
+ const content = update.content;
12260
+ if (content?.type === "text" && typeof content.text === "string") {
12261
+ this.partialThoughtContent += content.text;
12262
+ }
12263
+ this.currentStatus = "generating";
12264
+ break;
12265
+ }
12120
12266
  case "user_message_chunk": {
12121
12267
  break;
12122
12268
  }
@@ -12271,8 +12417,82 @@ var AcpProviderInstance = class {
12271
12417
  blocks.push(...this.partialBlocks);
12272
12418
  return blocks;
12273
12419
  }
12420
+ buildPartialThoughtMessage(timestamp = Date.now()) {
12421
+ const content = this.partialThoughtContent.trim();
12422
+ if (!content) return null;
12423
+ return buildThoughtChatMessage({
12424
+ content,
12425
+ timestamp,
12426
+ meta: {
12427
+ label: "Thought",
12428
+ isRunning: this.currentStatus === "generating"
12429
+ }
12430
+ });
12431
+ }
12432
+ buildToolCallBubbleKind(toolCall) {
12433
+ if (toolCall.kind === "think") return "thought";
12434
+ if (toolCall.kind === "execute") return "terminal";
12435
+ if (Array.isArray(toolCall.content) && toolCall.content.some((entry) => entry?.type === "terminal")) return "terminal";
12436
+ return "tool";
12437
+ }
12438
+ summarizeToolCallBubbleContent(toolCall) {
12439
+ const rawOutput = typeof toolCall.rawOutput === "string" ? toolCall.rawOutput.trim() : toolCall.rawOutput != null ? JSON.stringify(toolCall.rawOutput) : "";
12440
+ if (rawOutput) return rawOutput;
12441
+ const contentText = Array.isArray(toolCall.content) ? toolCall.content.map((entry) => {
12442
+ if (!entry || typeof entry !== "object") return "";
12443
+ if (entry.type === "content") return flattenContent([entry.content]).trim();
12444
+ if (entry.type === "diff") return `${entry.path}
12445
+ ${entry.newText || ""}`.trim();
12446
+ if (entry.type === "terminal") return `Terminal: ${entry.terminalId || ""}`.trim();
12447
+ return "";
12448
+ }).filter(Boolean).join("\n\n").trim() : "";
12449
+ if (contentText) return contentText;
12450
+ const rawInput = typeof toolCall.rawInput === "string" ? toolCall.rawInput.trim() : toolCall.rawInput != null ? JSON.stringify(toolCall.rawInput) : "";
12451
+ if (rawInput) {
12452
+ return toolCall.title ? `${toolCall.title}
12453
+ ${rawInput}` : rawInput;
12454
+ }
12455
+ return toolCall.title || "";
12456
+ }
12457
+ buildTurnToolCallMessages(timestamp = Date.now()) {
12458
+ return this.turnToolCalls.map((toolCall) => {
12459
+ const content = this.summarizeToolCallBubbleContent(toolCall);
12460
+ if (!content) return null;
12461
+ const isRunning = toolCall.status === "pending" || toolCall.status === "in_progress";
12462
+ const label = toolCall.title || void 0;
12463
+ const kind = this.buildToolCallBubbleKind(toolCall);
12464
+ if (kind === "thought") {
12465
+ return buildThoughtChatMessage({
12466
+ content,
12467
+ timestamp,
12468
+ meta: { label: label || "Thought", isRunning }
12469
+ });
12470
+ }
12471
+ if (kind === "terminal") {
12472
+ return buildTerminalChatMessage({
12473
+ content,
12474
+ timestamp,
12475
+ meta: { label: label || "Ran command", isRunning }
12476
+ });
12477
+ }
12478
+ return buildToolChatMessage({
12479
+ content,
12480
+ timestamp,
12481
+ meta: { label: label || "Tool call", isRunning }
12482
+ });
12483
+ }).filter(Boolean);
12484
+ }
12274
12485
  /** Finalize streaming content into an assistant message */
12275
12486
  finalizeAssistantMessage() {
12487
+ const timestamp = Date.now();
12488
+ const thoughtMessage = this.buildPartialThoughtMessage(timestamp);
12489
+ if (thoughtMessage) {
12490
+ this.messages.push(thoughtMessage);
12491
+ }
12492
+ const toolCallMessages = this.buildTurnToolCallMessages(timestamp);
12493
+ if (toolCallMessages.length > 0) {
12494
+ this.messages.push(...toolCallMessages);
12495
+ }
12276
12496
  const blocks = this.buildPartialBlocks();
12277
12497
  const finalBlocks = blocks.map((b) => {
12278
12498
  if (b.type === "text" && b.text.endsWith("...")) {
@@ -12288,6 +12508,7 @@ var AcpProviderInstance = class {
12288
12508
  }));
12289
12509
  }
12290
12510
  this.partialContent = "";
12511
+ this.partialThoughtContent = "";
12291
12512
  this.partialBlocks = [];
12292
12513
  this.turnToolCalls = [];
12293
12514
  }
@@ -15133,6 +15354,9 @@ function parseMessageTime(value) {
15133
15354
  }
15134
15355
  return 0;
15135
15356
  }
15357
+ function getMessageEventTime(message) {
15358
+ return parseMessageTime(message?.receivedAt) || parseMessageTime(message?.timestamp) || 0;
15359
+ }
15136
15360
  function stringifyPreviewContent(content) {
15137
15361
  if (typeof content === "string") return content;
15138
15362
  if (Array.isArray(content)) {
@@ -15177,7 +15401,7 @@ function getLastDisplayMessage(session) {
15177
15401
  return {
15178
15402
  role,
15179
15403
  preview,
15180
- receivedAt: parseMessageTime(candidate?.receivedAt),
15404
+ receivedAt: getMessageEventTime(candidate),
15181
15405
  hash: simplePreviewHash(`${role}:${preview}`)
15182
15406
  };
15183
15407
  }
@@ -15186,7 +15410,7 @@ function getLastDisplayMessage(session) {
15186
15410
  function getSessionMessageUpdatedAt(session) {
15187
15411
  const lastMessage = session.activeChat?.messages?.at?.(-1);
15188
15412
  if (!lastMessage) return 0;
15189
- return parseMessageTime(lastMessage.receivedAt) || 0;
15413
+ return getMessageEventTime(lastMessage);
15190
15414
  }
15191
15415
  function getSessionCompletionMarker(session) {
15192
15416
  const lastMessage = session.activeChat?.messages?.at?.(-1);
@@ -15196,7 +15420,7 @@ function getSessionCompletionMarker(session) {
15196
15420
  if (typeof lastMessage._turnKey === "string" && lastMessage._turnKey) return `turn:${lastMessage._turnKey}`;
15197
15421
  if (typeof lastMessage.id === "string" && lastMessage.id) return `id:${lastMessage.id}`;
15198
15422
  if (typeof lastMessage.index === "number" && Number.isFinite(lastMessage.index)) return `idx:${lastMessage.index}`;
15199
- const timestamp = parseMessageTime(lastMessage.receivedAt);
15423
+ const timestamp = getMessageEventTime(lastMessage);
15200
15424
  return timestamp > 0 ? `ts:${timestamp}` : "";
15201
15425
  }
15202
15426
  function getSessionLastUsedAt(session) {
@@ -16463,6 +16687,7 @@ var DEFAULT_DAEMON_PORT = 19222;
16463
16687
  var DAEMON_WS_PATH = "/ipc";
16464
16688
 
16465
16689
  // src/agent-stream/provider-adapter.ts
16690
+ init_chat_message_normalization();
16466
16691
  var ProviderStreamAdapter = class {
16467
16692
  agentType;
16468
16693
  agentName;
@@ -16572,7 +16797,7 @@ var ProviderStreamAdapter = class {
16572
16797
  agentName: this.agentName,
16573
16798
  extensionId: this.extensionId,
16574
16799
  status: data.status || "idle",
16575
- messages: data.messages || [],
16800
+ messages: normalizeChatMessages(Array.isArray(data.messages) ? data.messages : []),
16576
16801
  inputContent: data.inputContent || "",
16577
16802
  activeModal: data.activeModal
16578
16803
  };
@@ -23710,6 +23935,8 @@ export {
23710
23935
  CdpDomHandlers,
23711
23936
  CliProviderInstance,
23712
23937
  DAEMON_WS_PATH,
23938
+ DEFAULT_ACTIVE_CHAT_POLL_STATUSES,
23939
+ DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS,
23713
23940
  DEFAULT_DAEMON_PORT,
23714
23941
  DEFAULT_SESSION_HOST_APP_NAME,
23715
23942
  DEFAULT_STANDALONE_SESSION_HOST_APP_NAME,
@@ -23738,7 +23965,11 @@ export {
23738
23965
  buildSessionEntries,
23739
23966
  buildStatusSnapshot,
23740
23967
  buildSystemChatMessage,
23968
+ buildTerminalChatMessage,
23969
+ buildThoughtChatMessage,
23970
+ buildToolChatMessage,
23741
23971
  buildUserChatMessage,
23972
+ classifyHotChatSessionsForSubscriptionFlush,
23742
23973
  clearDebugTrace,
23743
23974
  configureDebugTraceStore,
23744
23975
  connectCdpManager,
@@ -23805,6 +24036,7 @@ export {
23805
24036
  resetConfig,
23806
24037
  resetDebugRuntimeConfig,
23807
24038
  resetState,
24039
+ resolveChatMessageKind,
23808
24040
  resolveDebugRuntimeConfig,
23809
24041
  resolveSessionHostAppName,
23810
24042
  saveConfig,