@adhdev/daemon-core 0.9.76-rc.54 → 0.9.76-rc.56

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.76-rc.54",
3
+ "version": "0.9.76-rc.56",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,8 +18,8 @@ import { LOG, getRecentLogs } from '../logging/logger.js';
18
18
  import { getRecentDebugTrace, recordDebugTrace } from '../logging/debug-trace.js';
19
19
  import { buildChatMessageSignature } from '../chat/chat-signatures.js';
20
20
  import type { ChatMessage } from '../types.js';
21
- import { filterUserFacingChatMessages } from '../providers/chat-message-normalization.js';
22
21
  import type { SessionTransport } from '../shared-types.js';
22
+ import { filterUserFacingChatMessages, normalizeChatMessages } from '../providers/chat-message-normalization.js';
23
23
 
24
24
  const RECENT_SEND_WINDOW_MS = 1200;
25
25
  export const READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25_000;
@@ -196,7 +196,7 @@ function normalizeReadChatTailLimit(args: any): number {
196
196
 
197
197
  function normalizeReadChatMessages(payload: Record<string, any>): ChatMessage[] {
198
198
  const messages = Array.isArray(payload.messages) ? payload.messages as ChatMessage[] : [];
199
- return messages;
199
+ return normalizeChatMessages(messages);
200
200
  }
201
201
 
202
202
 
@@ -25,7 +25,7 @@ import { formatAutoApprovalMessage, pickApprovalButton } from './approval-utils.
25
25
  import { getCliScriptCommand, parseCliScriptResult } from './cli-script-results.js';
26
26
  import { mergeProviderPatchState, resolveProviderStateSurface } from './provider-patch-state.js';
27
27
  import { normalizeProviderSessionId } from './provider-session-id.js';
28
- import { buildChatMessage, buildRuntimeSystemChatMessage, normalizeChatMessages } from './chat-message-normalization.js';
28
+ import { buildChatMessage, buildRuntimeSystemChatMessage, isUserFacingChatMessage, normalizeChatMessages, resolveChatMessageKind } from './chat-message-normalization.js';
29
29
 
30
30
  type PersistableCliHistoryMessage = {
31
31
  role: string;
@@ -1007,7 +1007,7 @@ export class CliProviderInstance implements ProviderInstance {
1007
1007
  private mergeConversationMessages(parsedMessages: any[]): ChatMessage[] {
1008
1008
  if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
1009
1009
 
1010
- type MergeEntry = { message: ChatMessage; index: number; source: 'parsed' | 'runtime' };
1010
+ type MergeEntry = { message: ChatMessage; index: number; source: 'parsed' | 'runtime'; runtimeKey?: string };
1011
1011
  const parsedEntries: MergeEntry[] = parsedMessages.map((message, index) => ({
1012
1012
  message,
1013
1013
  index,
@@ -1017,6 +1017,7 @@ export class CliProviderInstance implements ProviderInstance {
1017
1017
  message: entry.message,
1018
1018
  index: parsedMessages.length + index,
1019
1019
  source: 'runtime',
1020
+ runtimeKey: entry.key,
1020
1021
  }));
1021
1022
  const getTime = (message: ChatMessage): number => {
1022
1023
  const value = typeof message.receivedAt === 'number'
@@ -1027,16 +1028,49 @@ export class CliProviderInstance implements ProviderInstance {
1027
1028
  return Number.isFinite(value) && value > 0 ? value : 0;
1028
1029
  };
1029
1030
 
1031
+ const getRole = (message: ChatMessage): string => typeof message.role === 'string'
1032
+ ? message.role.trim().toLowerCase()
1033
+ : '';
1034
+ const isRuntimeOverlay = (entry: MergeEntry): boolean => {
1035
+ if (entry.source !== 'runtime') return false;
1036
+ const key = typeof entry.runtimeKey === 'string' ? entry.runtimeKey.trim().toLowerCase() : '';
1037
+ if (key.startsWith('auto_approval:')) return true;
1038
+ return !isUserFacingChatMessage(entry.message);
1039
+ };
1040
+ const shouldKeepParsedBeforeUntimedRuntime = (message: ChatMessage): boolean => {
1041
+ const role = getRole(message);
1042
+ return role === 'user' || role === 'human';
1043
+ };
1044
+ const shouldKeepParsedAfterUntimedRuntime = (message: ChatMessage): boolean => {
1045
+ const role = getRole(message);
1046
+ if (role !== 'assistant') return false;
1047
+ const kind = resolveChatMessageKind(message);
1048
+ return kind === 'standard' || kind === 'terminal';
1049
+ };
1050
+
1030
1051
  return normalizeChatMessages([...parsedEntries, ...runtimeEntries]
1031
1052
  .sort((a, b) => {
1032
1053
  const aTime = getTime(a.message);
1033
1054
  const bTime = getTime(b.message);
1034
1055
  if (aTime && bTime && aTime !== bTime) return aTime - bTime;
1056
+ if (a.source !== b.source && aTime !== bTime) {
1057
+ const parsedEntry = a.source === 'parsed' ? a : b.source === 'parsed' ? b : null;
1058
+ const runtimeEntry = a.source === 'runtime' ? a : b.source === 'runtime' ? b : null;
1059
+ if (parsedEntry && runtimeEntry && isRuntimeOverlay(runtimeEntry) && getTime(parsedEntry.message) === 0 && getTime(runtimeEntry.message) > 0) {
1060
+ if (shouldKeepParsedBeforeUntimedRuntime(parsedEntry.message)) {
1061
+ return a.source === 'parsed' ? -1 : 1;
1062
+ }
1063
+ if (shouldKeepParsedAfterUntimedRuntime(parsedEntry.message)) {
1064
+ return a.source === 'parsed' ? 1 : -1;
1065
+ }
1066
+ }
1067
+ }
1035
1068
  // Many provider-owned CLI transcripts (including Hermes CLI in debug bundles)
1036
1069
  // do not carry timestamps on parsed messages. In that case there is no safe
1037
1070
  // clock basis for interleaving timestamped runtime/system messages into the
1038
- // provider transcript, so preserve parsed order and append runtime entries by
1039
- // their insertion index instead of moving them ahead of the whole transcript.
1071
+ // provider transcript. Keep user prompts before runtime overlays, but do not
1072
+ // let timed runtime/system/tool/internal overlays become the final chat turns
1073
+ // after an untimed parsed assistant transcript.
1040
1074
  return a.index - b.index;
1041
1075
  })
1042
1076
  .map((entry) => entry.message));