@adhdev/daemon-standalone 0.8.60 → 0.8.61

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
@@ -28313,6 +28313,63 @@ var require_dist2 = __commonJS({
28313
28313
  LOG_PATH = path6.join(LOG_DIR, `daemon-${getDateStr()}.log`);
28314
28314
  }
28315
28315
  });
28316
+ function isBuiltinChatMessageKind(kind) {
28317
+ return typeof kind === "string" && KNOWN_CHAT_MESSAGE_KINDS.has(kind.trim().toLowerCase());
28318
+ }
28319
+ function normalizeChatMessageKind(kind, role) {
28320
+ const normalizedKind = typeof kind === "string" ? kind.trim().toLowerCase() : "";
28321
+ if (normalizedKind && KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
28322
+ const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
28323
+ return normalizedRole === "system" ? "system" : "standard";
28324
+ }
28325
+ function buildChatMessage(message) {
28326
+ return {
28327
+ ...message,
28328
+ kind: normalizeChatMessageKind(message?.kind, message?.role)
28329
+ };
28330
+ }
28331
+ function buildSystemChatMessage(message) {
28332
+ return buildChatMessage({
28333
+ ...message,
28334
+ role: "system",
28335
+ kind: message?.kind || "system"
28336
+ });
28337
+ }
28338
+ function buildRuntimeSystemChatMessage(message) {
28339
+ return buildSystemChatMessage({
28340
+ ...message,
28341
+ senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
28342
+ });
28343
+ }
28344
+ function buildAssistantChatMessage(message) {
28345
+ return buildChatMessage({
28346
+ ...message,
28347
+ role: "assistant",
28348
+ kind: message?.kind || "standard"
28349
+ });
28350
+ }
28351
+ function buildUserChatMessage(message) {
28352
+ return buildChatMessage({
28353
+ ...message,
28354
+ role: "user",
28355
+ kind: message?.kind || "standard"
28356
+ });
28357
+ }
28358
+ function normalizeChatMessage(message) {
28359
+ return buildChatMessage(message);
28360
+ }
28361
+ function normalizeChatMessages(messages) {
28362
+ return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
28363
+ }
28364
+ var BUILTIN_CHAT_MESSAGE_KINDS;
28365
+ var KNOWN_CHAT_MESSAGE_KINDS;
28366
+ var init_chat_message_normalization = __esm2({
28367
+ "src/providers/chat-message-normalization.ts"() {
28368
+ "use strict";
28369
+ BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
28370
+ KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
28371
+ }
28372
+ });
28316
28373
  function isModuleNotFoundError(error48, ref) {
28317
28374
  if (!(error48 instanceof Error)) return false;
28318
28375
  const message = error48.message || "";
@@ -29160,6 +29217,7 @@ var require_dist2 = __commonJS({
29160
29217
  init_terminal_screen();
29161
29218
  init_pty_transport();
29162
29219
  init_provider_cli_shared();
29220
+ init_chat_message_normalization();
29163
29221
  init_provider_cli_parse();
29164
29222
  init_provider_cli_config();
29165
29223
  init_provider_cli_runtime();
@@ -30217,11 +30275,10 @@ var require_dist2 = __commonJS({
30217
30275
  );
30218
30276
  const shouldPreferCommittedMessages = !this.currentTurnScope && this.currentStatus === "idle" && !this.activeModal;
30219
30277
  if (parsed && Array.isArray(parsed.messages)) {
30220
- const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => ({
30278
+ const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => buildChatMessage({
30221
30279
  ...message,
30222
30280
  id: message.id || `msg_${index}`,
30223
30281
  index: typeof message.index === "number" ? message.index : index,
30224
- kind: message.kind || "standard",
30225
30282
  receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
30226
30283
  })) : hydrateCliParsedMessages(parsed.messages, {
30227
30284
  committedMessages: this.committedMessages,
@@ -30242,13 +30299,11 @@ var require_dist2 = __commonJS({
30242
30299
  id: "cli_session",
30243
30300
  status: this.currentStatus,
30244
30301
  title: this.cliName,
30245
- messages: messages.slice(-50).map((message, index) => ({
30246
- id: `msg_${index}`,
30247
- role: message.role,
30248
- content: message.content,
30249
- timestamp: message.timestamp,
30250
- index,
30251
- kind: "standard"
30302
+ messages: messages.slice(-50).map((message, index) => buildChatMessage({
30303
+ ...message,
30304
+ id: message.id || `msg_${index}`,
30305
+ index: typeof message.index === "number" ? message.index : index,
30306
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
30252
30307
  })),
30253
30308
  activeModal: this.activeModal
30254
30309
  };
@@ -30871,6 +30926,7 @@ ${data.message || ""}`.trim();
30871
30926
  __export2(index_exports, {
30872
30927
  AcpProviderInstance: () => AcpProviderInstance,
30873
30928
  AgentStreamPoller: () => AgentStreamPoller,
30929
+ BUILTIN_CHAT_MESSAGE_KINDS: () => BUILTIN_CHAT_MESSAGE_KINDS,
30874
30930
  CdpDomHandlers: () => CdpDomHandlers,
30875
30931
  CliProviderInstance: () => CliProviderInstance,
30876
30932
  DAEMON_WS_PATH: () => DAEMON_WS_PATH,
@@ -30895,9 +30951,14 @@ ${data.message || ""}`.trim();
30895
30951
  SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
30896
30952
  VersionArchive: () => VersionArchive,
30897
30953
  appendRecentActivity: () => appendRecentActivity,
30954
+ buildAssistantChatMessage: () => buildAssistantChatMessage,
30955
+ buildChatMessage: () => buildChatMessage,
30898
30956
  buildMachineInfo: () => buildMachineInfo2,
30957
+ buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
30899
30958
  buildSessionEntries: () => buildSessionEntries,
30900
30959
  buildStatusSnapshot: () => buildStatusSnapshot2,
30960
+ buildSystemChatMessage: () => buildSystemChatMessage,
30961
+ buildUserChatMessage: () => buildUserChatMessage,
30901
30962
  clearDebugTrace: () => clearDebugTrace,
30902
30963
  configureDebugTraceStore: () => configureDebugTraceStore,
30903
30964
  connectCdpManager: () => connectCdpManager,
@@ -30929,6 +30990,7 @@ ${data.message || ""}`.trim();
30929
30990
  initDaemonComponents: () => initDaemonComponents2,
30930
30991
  installExtensions: () => installExtensions,
30931
30992
  installGlobalInterceptor: () => installGlobalInterceptor,
30993
+ isBuiltinChatMessageKind: () => isBuiltinChatMessageKind,
30932
30994
  isCdpConnected: () => isCdpConnected,
30933
30995
  isExtensionInstalled: () => isExtensionInstalled,
30934
30996
  isIdeRunning: () => isIdeRunning,
@@ -30947,6 +31009,9 @@ ${data.message || ""}`.trim();
30947
31009
  markSetupComplete: () => markSetupComplete,
30948
31010
  maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv2,
30949
31011
  normalizeActiveChatData: () => normalizeActiveChatData,
31012
+ normalizeChatMessage: () => normalizeChatMessage,
31013
+ normalizeChatMessageKind: () => normalizeChatMessageKind,
31014
+ normalizeChatMessages: () => normalizeChatMessages,
30950
31015
  normalizeInputEnvelope: () => normalizeInputEnvelope,
30951
31016
  normalizeManagedStatus: () => normalizeManagedStatus,
30952
31017
  normalizeMessageParts: () => normalizeMessageParts,
@@ -32928,6 +32993,215 @@ ${data.message || ""}`.trim();
32928
32993
  }
32929
32994
  };
32930
32995
  var crypto2 = __toESM2(require("crypto"));
32996
+ function normalizeInputEnvelope(input) {
32997
+ const normalized = normalizeInputEnvelopePayload(input);
32998
+ const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
32999
+ return {
33000
+ parts: normalized.parts,
33001
+ textFallback,
33002
+ ...normalized.metadata ? { metadata: normalized.metadata } : {}
33003
+ };
33004
+ }
33005
+ function normalizeMessageParts(content) {
33006
+ if (typeof content === "string") return [{ type: "text", text: content }];
33007
+ if (!Array.isArray(content)) {
33008
+ if (content && typeof content === "object" && typeof content.text === "string") {
33009
+ return [{ type: "text", text: String(content.text) }];
33010
+ }
33011
+ return [];
33012
+ }
33013
+ const parts = [];
33014
+ for (const raw of content) {
33015
+ if (typeof raw === "string") {
33016
+ parts.push({ type: "text", text: raw });
33017
+ continue;
33018
+ }
33019
+ if (!raw || typeof raw !== "object") continue;
33020
+ const part = normalizeMessagePartObject(raw);
33021
+ if (part) parts.push(part);
33022
+ }
33023
+ return parts;
33024
+ }
33025
+ function flattenMessageParts(parts) {
33026
+ return parts.map((part) => {
33027
+ if (part.type === "text") return part.text;
33028
+ if (part.type === "resource") return part.resource.text || "";
33029
+ return "";
33030
+ }).filter((value) => value.length > 0).join("\n");
33031
+ }
33032
+ function normalizeInputEnvelopePayload(input) {
33033
+ if (typeof input === "string") {
33034
+ return { parts: [{ type: "text", text: input }], textFallback: input };
33035
+ }
33036
+ if (!input || typeof input !== "object") {
33037
+ return { parts: [], textFallback: "" };
33038
+ }
33039
+ const record2 = input;
33040
+ const nestedInput = record2.input;
33041
+ if (nestedInput && typeof nestedInput === "object") {
33042
+ const nested = nestedInput;
33043
+ return {
33044
+ parts: normalizeInputParts(nested.parts ?? nested.prompt),
33045
+ textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
33046
+ metadata: normalizeInputMetadata(nested.metadata)
33047
+ };
33048
+ }
33049
+ const directText = typeof record2.text === "string" ? record2.text : typeof record2.message === "string" ? record2.message : void 0;
33050
+ if (directText !== void 0) {
33051
+ return { parts: [{ type: "text", text: directText }], textFallback: directText };
33052
+ }
33053
+ const directParts = normalizeInputParts(record2.parts ?? record2.prompt);
33054
+ return {
33055
+ parts: directParts,
33056
+ textFallback: typeof record2.textFallback === "string" ? record2.textFallback : void 0,
33057
+ metadata: normalizeInputMetadata(record2.metadata)
33058
+ };
33059
+ }
33060
+ function normalizeInputMetadata(value) {
33061
+ if (!value || typeof value !== "object") return void 0;
33062
+ const record2 = value;
33063
+ const metadata = {};
33064
+ if (record2.source === "dashboard" || record2.source === "shortcut_api" || record2.source === "provider_script" || record2.source === "session_replay") {
33065
+ metadata.source = record2.source;
33066
+ }
33067
+ if (typeof record2.clientTimestamp === "number" && Number.isFinite(record2.clientTimestamp)) {
33068
+ metadata.clientTimestamp = record2.clientTimestamp;
33069
+ }
33070
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
33071
+ }
33072
+ function normalizeInputParts(value) {
33073
+ if (!Array.isArray(value)) return [];
33074
+ const parts = [];
33075
+ for (const raw of value) {
33076
+ if (typeof raw === "string") {
33077
+ parts.push({ type: "text", text: raw });
33078
+ continue;
33079
+ }
33080
+ if (!raw || typeof raw !== "object") continue;
33081
+ const part = normalizeInputPartObject(raw);
33082
+ if (part) parts.push(part);
33083
+ }
33084
+ return parts;
33085
+ }
33086
+ function normalizeInputPartObject(raw) {
33087
+ const type = raw.type;
33088
+ if (type === "text" && typeof raw.text === "string") {
33089
+ return { type, text: raw.text };
33090
+ }
33091
+ if (type === "image" && typeof raw.mimeType === "string") {
33092
+ return {
33093
+ type,
33094
+ mimeType: raw.mimeType,
33095
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
33096
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
33097
+ ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
33098
+ };
33099
+ }
33100
+ if (type === "audio" && typeof raw.mimeType === "string") {
33101
+ return {
33102
+ type,
33103
+ mimeType: raw.mimeType,
33104
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
33105
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
33106
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
33107
+ };
33108
+ }
33109
+ if (type === "video" && typeof raw.mimeType === "string") {
33110
+ return {
33111
+ type,
33112
+ mimeType: raw.mimeType,
33113
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
33114
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
33115
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
33116
+ };
33117
+ }
33118
+ if (type === "resource" && typeof raw.uri === "string") {
33119
+ return {
33120
+ type,
33121
+ uri: raw.uri,
33122
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
33123
+ ...typeof raw.name === "string" ? { name: raw.name } : {},
33124
+ ...typeof raw.text === "string" ? { text: raw.text } : {},
33125
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
33126
+ };
33127
+ }
33128
+ if (type === "resource_link" && typeof raw.uri === "string") {
33129
+ return {
33130
+ type: "resource",
33131
+ uri: raw.uri,
33132
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
33133
+ ...typeof raw.name === "string" ? { name: raw.name } : {}
33134
+ };
33135
+ }
33136
+ return null;
33137
+ }
33138
+ function normalizeMessagePartObject(raw) {
33139
+ const type = raw.type;
33140
+ if (type === "text" && typeof raw.text === "string") {
33141
+ return { type, text: raw.text };
33142
+ }
33143
+ if (type === "image" && typeof raw.mimeType === "string") {
33144
+ return {
33145
+ type,
33146
+ mimeType: raw.mimeType,
33147
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
33148
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
33149
+ };
33150
+ }
33151
+ if (type === "audio" && typeof raw.mimeType === "string") {
33152
+ return {
33153
+ type,
33154
+ mimeType: raw.mimeType,
33155
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
33156
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
33157
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
33158
+ };
33159
+ }
33160
+ if (type === "video" && typeof raw.mimeType === "string") {
33161
+ return {
33162
+ type,
33163
+ mimeType: raw.mimeType,
33164
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
33165
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
33166
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
33167
+ };
33168
+ }
33169
+ if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
33170
+ return {
33171
+ type,
33172
+ uri: raw.uri,
33173
+ name: raw.name,
33174
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
33175
+ ...typeof raw.size === "number" ? { size: raw.size } : {}
33176
+ };
33177
+ }
33178
+ if (type === "resource" && raw.resource && typeof raw.resource === "object") {
33179
+ const resource = raw.resource;
33180
+ if (typeof resource.uri !== "string") return null;
33181
+ return {
33182
+ type,
33183
+ resource: {
33184
+ uri: resource.uri,
33185
+ ...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
33186
+ ...typeof resource.text === "string" ? { text: resource.text } : {},
33187
+ ...typeof resource.blob === "string" ? { blob: resource.blob } : {}
33188
+ }
33189
+ };
33190
+ }
33191
+ return null;
33192
+ }
33193
+ function flattenInputParts(parts) {
33194
+ return parts.map((part) => {
33195
+ if (part.type === "text") return part.text;
33196
+ if (part.type === "audio") return part.transcript || "";
33197
+ if (part.type === "resource") return part.text || "";
33198
+ return "";
33199
+ }).filter((value) => value.length > 0).join("\n");
33200
+ }
33201
+ function flattenContent(content) {
33202
+ if (typeof content === "string") return content;
33203
+ return flattenMessageParts(normalizeMessageParts(content));
33204
+ }
32931
33205
  var DEFAULT_MONITOR_CONFIG = {
32932
33206
  approvalAlert: true,
32933
33207
  longGeneratingAlert: true,
@@ -33038,6 +33312,7 @@ ${data.message || ""}`.trim();
33038
33312
  }
33039
33313
  }
33040
33314
  };
33315
+ init_chat_message_normalization();
33041
33316
  function extractProviderControlValues(controls, data) {
33042
33317
  if (!data || typeof data !== "object") return void 0;
33043
33318
  const values = {};
@@ -33105,13 +33380,58 @@ ${data.message || ""}`.trim();
33105
33380
  level: raw.notification.level === "success" || raw.notification.level === "warning" ? raw.notification.level : "info",
33106
33381
  channels: Array.isArray(raw.notification.channels) ? raw.notification.channels.filter((channel) => channel === "bubble" || channel === "toast" || channel === "browser") : void 0,
33107
33382
  preferenceKey: raw.notification.preferenceKey === "disconnect" || raw.notification.preferenceKey === "completion" || raw.notification.preferenceKey === "approval" || raw.notification.preferenceKey === "browser" ? raw.notification.preferenceKey : void 0,
33108
- bubbleContent: typeof raw.notification.bubbleContent === "string" || Array.isArray(raw.notification.bubbleContent) ? raw.notification.bubbleContent : void 0
33383
+ bubbleContent: typeof raw.notification.bubbleContent === "string" || Array.isArray(raw.notification.bubbleContent) ? raw.notification.bubbleContent : void 0,
33384
+ bubbleKind: typeof raw.notification.bubbleKind === "string" ? raw.notification.bubbleKind : void 0,
33385
+ bubbleRole: raw.notification.bubbleRole === "assistant" || raw.notification.bubbleRole === "user" ? raw.notification.bubbleRole : raw.notification.bubbleRole === "system" ? "system" : void 0,
33386
+ bubbleSenderName: typeof raw.notification.bubbleSenderName === "string" ? raw.notification.bubbleSenderName : void 0
33109
33387
  }
33110
33388
  });
33111
33389
  }
33112
33390
  }
33113
33391
  return effects;
33114
33392
  }
33393
+ function buildPersistedProviderEffectMessage(effect) {
33394
+ if (!effect) return null;
33395
+ if (effect.type === "message" && effect.message) {
33396
+ const role = effect.message.role === "assistant" || effect.message.role === "user" ? effect.message.role : "system";
33397
+ if (role === "system") {
33398
+ return buildRuntimeSystemChatMessage({
33399
+ content: effect.message.content,
33400
+ kind: effect.message.kind,
33401
+ senderName: effect.message.senderName
33402
+ });
33403
+ }
33404
+ return buildChatMessage({
33405
+ role,
33406
+ content: effect.message.content,
33407
+ kind: effect.message.kind,
33408
+ senderName: effect.message.senderName
33409
+ });
33410
+ }
33411
+ if (effect.type === "notification" && effect.notification) {
33412
+ const bubbleContent = effect.notification.bubbleContent ?? formatNotificationBubbleFallback(effect.notification.title, effect.notification.body);
33413
+ const flattened = typeof bubbleContent === "string" ? bubbleContent.trim() : flattenContent(bubbleContent).trim();
33414
+ if (!flattened && (!Array.isArray(bubbleContent) || bubbleContent.length === 0)) return null;
33415
+ const role = effect.notification.bubbleRole === "assistant" || effect.notification.bubbleRole === "user" ? effect.notification.bubbleRole : "system";
33416
+ if (role === "system") {
33417
+ return buildRuntimeSystemChatMessage({
33418
+ content: bubbleContent,
33419
+ kind: effect.notification.bubbleKind,
33420
+ senderName: effect.notification.bubbleSenderName
33421
+ });
33422
+ }
33423
+ return buildChatMessage({
33424
+ role,
33425
+ content: bubbleContent,
33426
+ kind: effect.notification.bubbleKind,
33427
+ senderName: effect.notification.bubbleSenderName
33428
+ });
33429
+ }
33430
+ if (effect.type === "toast" && effect.toast?.message) {
33431
+ return buildRuntimeSystemChatMessage({ content: effect.toast.message });
33432
+ }
33433
+ return null;
33434
+ }
33115
33435
  function normalizeControlListResult(data) {
33116
33436
  if (data && typeof data === "object" && Array.isArray(data.options)) {
33117
33437
  return {
@@ -33178,9 +33498,17 @@ ${data.message || ""}`.trim();
33178
33498
  }
33179
33499
  return String(value);
33180
33500
  }
33501
+ function formatNotificationBubbleFallback(title, body) {
33502
+ const cleanTitle = typeof title === "string" ? title.trim() : "";
33503
+ const cleanBody = String(body || "").trim();
33504
+ if (cleanTitle && cleanBody) return `${cleanTitle}
33505
+ ${cleanBody}`;
33506
+ return cleanTitle || cleanBody;
33507
+ }
33181
33508
  var fs32 = __toESM2(require("fs"));
33182
33509
  var path7 = __toESM2(require("path"));
33183
33510
  var os52 = __toESM2(require("os"));
33511
+ init_chat_message_normalization();
33184
33512
  var HISTORY_DIR = path7.join(os52.homedir(), ".adhdev", "history");
33185
33513
  var RETAIN_DAYS = 30;
33186
33514
  var CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
@@ -33386,11 +33714,11 @@ ${data.message || ""}`.trim();
33386
33714
  this.appendNewMessages(
33387
33715
  agentType,
33388
33716
  [{
33389
- role: "system",
33390
- kind: "system",
33391
- content,
33392
- receivedAt: options.receivedAt,
33393
- senderName: options.senderName,
33717
+ ...buildRuntimeSystemChatMessage({
33718
+ content,
33719
+ receivedAt: options.receivedAt,
33720
+ senderName: options.senderName
33721
+ }),
33394
33722
  historyDedupKey: options.dedupKey
33395
33723
  }],
33396
33724
  options.sessionTitle,
@@ -33741,6 +34069,7 @@ ${data.message || ""}`.trim();
33741
34069
  })
33742
34070
  };
33743
34071
  }
34072
+ init_chat_message_normalization();
33744
34073
  var ExtensionProviderInstance = class {
33745
34074
  type;
33746
34075
  category = "extension";
@@ -33947,8 +34276,8 @@ ${data.message || ""}`.trim();
33947
34276
  if (this.appliedEffectKeys.has(effectKey)) continue;
33948
34277
  this.appliedEffectKeys.add(effectKey);
33949
34278
  if (effect.persist !== false) {
33950
- const persisted = this.getPersistedEffectContent(effect);
33951
- if (persisted) this.appendRuntimeSystemMessage(persisted, effectKey);
34279
+ const persistedMessage = buildPersistedProviderEffectMessage(effect);
34280
+ if (persistedMessage) this.appendRuntimeMessage(persistedMessage, effectKey);
33952
34281
  }
33953
34282
  if (effect.type === "message" && effect.message) {
33954
34283
  this.pushEvent({
@@ -33983,34 +34312,42 @@ ${data.message || ""}`.trim();
33983
34312
  }
33984
34313
  }
33985
34314
  appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
33986
- const normalizedContent = String(content || "").trim();
33987
- if (!normalizedContent) return;
34315
+ this.appendRuntimeMessage(buildRuntimeSystemChatMessage({
34316
+ content,
34317
+ receivedAt,
34318
+ timestamp: receivedAt
34319
+ }), dedupKey);
34320
+ }
34321
+ appendRuntimeMessage(message, dedupKey) {
34322
+ const normalizedMessage = buildChatMessage({
34323
+ ...message,
34324
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp || Date.now(),
34325
+ timestamp: typeof message.timestamp === "number" ? message.timestamp : message.receivedAt || Date.now()
34326
+ });
34327
+ const normalizedContent = typeof normalizedMessage.content === "string" ? normalizedMessage.content.trim() : flattenContent(normalizedMessage.content).trim();
34328
+ if (!normalizedContent && (!Array.isArray(normalizedMessage.content) || normalizedMessage.content.length === 0)) return;
33988
34329
  if (this.runtimeMessages.some((entry) => entry.key === dedupKey)) return;
33989
34330
  this.runtimeMessages.push({
33990
34331
  key: dedupKey,
33991
- message: {
33992
- role: "system",
33993
- senderName: "System",
33994
- content: normalizedContent,
33995
- receivedAt,
33996
- timestamp: receivedAt
33997
- }
34332
+ message: normalizedMessage
33998
34333
  });
33999
34334
  if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
34000
- this.historyWriter.appendNewMessages(
34001
- this.type,
34002
- [{
34003
- role: "system",
34004
- senderName: "System",
34005
- content: normalizedContent,
34006
- kind: "system",
34007
- receivedAt,
34008
- historyDedupKey: dedupKey
34009
- }],
34010
- this.chatTitle || this.agentName || this.provider.name,
34011
- this.instanceId,
34012
- this.chatId || this.instanceId
34013
- );
34335
+ if (normalizedContent) {
34336
+ this.historyWriter.appendNewMessages(
34337
+ this.type,
34338
+ [{
34339
+ role: normalizedMessage.role,
34340
+ senderName: normalizedMessage.senderName,
34341
+ kind: normalizedMessage.kind,
34342
+ content: normalizedContent,
34343
+ receivedAt: normalizedMessage.receivedAt || normalizedMessage.timestamp,
34344
+ historyDedupKey: dedupKey
34345
+ }],
34346
+ this.chatTitle || this.agentName || this.provider.name,
34347
+ this.instanceId,
34348
+ this.chatId || this.instanceId
34349
+ );
34350
+ }
34014
34351
  }
34015
34352
  /**
34016
34353
  * Assign stable receivedAt to extension messages.
@@ -34027,16 +34364,16 @@ ${data.message || ""}`.trim();
34027
34364
  nextHashes.set(hash2, msg.receivedAt);
34028
34365
  }
34029
34366
  this.prevMessageHashes = nextHashes;
34030
- return messages;
34367
+ return normalizeChatMessages(messages);
34031
34368
  }
34032
34369
  mergeConversationMessages(messages) {
34033
- if (this.runtimeMessages.length === 0) return messages;
34034
- return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
34370
+ if (this.runtimeMessages.length === 0) return normalizeChatMessages(messages);
34371
+ return normalizeChatMessages([...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
34035
34372
  const aTime = a.message.receivedAt || a.message.timestamp || 0;
34036
34373
  const bTime = b2.message.receivedAt || b2.message.timestamp || 0;
34037
34374
  if (aTime !== bTime) return aTime - bTime;
34038
34375
  return a.index - b2.index;
34039
- }).map((entry) => entry.message);
34376
+ }).map((entry) => entry.message));
34040
34377
  }
34041
34378
  getPersistedEffectContent(effect) {
34042
34379
  if (effect.type === "message") {
@@ -34144,6 +34481,7 @@ ${effect.notification.body || ""}`.trim();
34144
34481
  if (cleanMessage) lines.push(cleanMessage);
34145
34482
  return lines.join("\n");
34146
34483
  }
34484
+ init_chat_message_normalization();
34147
34485
  var IdeProviderInstance = class {
34148
34486
  type;
34149
34487
  category = "ide";
@@ -34524,8 +34862,8 @@ ${effect.notification.body || ""}`.trim();
34524
34862
  if (this.appliedEffectKeys.has(effectKey)) continue;
34525
34863
  this.appliedEffectKeys.add(effectKey);
34526
34864
  if (effect.persist !== false) {
34527
- const persisted = this.getPersistedEffectContent(effect);
34528
- if (persisted) this.appendRuntimeSystemMessage(persisted, effectKey);
34865
+ const persistedMessage = buildPersistedProviderEffectMessage(effect);
34866
+ if (persistedMessage) this.appendRuntimeMessage(persistedMessage, effectKey);
34529
34867
  }
34530
34868
  if (effect.type === "message" && effect.message) {
34531
34869
  this.pushEvent({
@@ -34560,8 +34898,20 @@ ${effect.notification.body || ""}`.trim();
34560
34898
  }
34561
34899
  }
34562
34900
  appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
34563
- const normalizedContent = String(content || "").trim();
34564
- if (!normalizedContent) return;
34901
+ this.appendRuntimeMessage(buildRuntimeSystemChatMessage({
34902
+ content,
34903
+ receivedAt,
34904
+ timestamp: receivedAt
34905
+ }), dedupKey);
34906
+ }
34907
+ appendRuntimeMessage(message, dedupKey) {
34908
+ const normalizedMessage = buildChatMessage({
34909
+ ...message,
34910
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp || Date.now(),
34911
+ timestamp: typeof message.timestamp === "number" ? message.timestamp : message.receivedAt || Date.now()
34912
+ });
34913
+ const normalizedContent = typeof normalizedMessage.content === "string" ? normalizedMessage.content.trim() : flattenContent(normalizedMessage.content).trim();
34914
+ if (!normalizedContent && (!Array.isArray(normalizedMessage.content) || normalizedMessage.content.length === 0)) return;
34565
34915
  if (this.runtimeMessages.some((entry) => entry.key === dedupKey)) return;
34566
34916
  if (!this.cachedChat) {
34567
34917
  this.cachedChat = {
@@ -34575,38 +34925,34 @@ ${effect.notification.body || ""}`.trim();
34575
34925
  }
34576
34926
  this.runtimeMessages.push({
34577
34927
  key: dedupKey,
34578
- message: {
34579
- role: "system",
34580
- senderName: "System",
34581
- content: normalizedContent,
34582
- receivedAt,
34583
- timestamp: receivedAt
34584
- }
34928
+ message: normalizedMessage
34585
34929
  });
34586
34930
  if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
34587
- this.historyWriter.appendNewMessages(
34588
- this.type,
34589
- [{
34590
- role: "system",
34591
- senderName: "System",
34592
- content: normalizedContent,
34593
- kind: "system",
34594
- receivedAt,
34595
- historyDedupKey: dedupKey
34596
- }],
34597
- this.cachedChat?.title || this.provider.name,
34598
- this.instanceId,
34599
- this.cachedChat?.id || this.instanceId
34600
- );
34931
+ if (normalizedContent) {
34932
+ this.historyWriter.appendNewMessages(
34933
+ this.type,
34934
+ [{
34935
+ role: normalizedMessage.role,
34936
+ senderName: normalizedMessage.senderName,
34937
+ kind: normalizedMessage.kind,
34938
+ content: normalizedContent,
34939
+ receivedAt: normalizedMessage.receivedAt || normalizedMessage.timestamp,
34940
+ historyDedupKey: dedupKey
34941
+ }],
34942
+ this.cachedChat?.title || this.provider.name,
34943
+ this.instanceId,
34944
+ this.cachedChat?.id || this.instanceId
34945
+ );
34946
+ }
34601
34947
  }
34602
34948
  mergeConversationMessages(messages) {
34603
- if (this.runtimeMessages.length === 0) return messages;
34604
- return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
34949
+ if (this.runtimeMessages.length === 0) return normalizeChatMessages(messages);
34950
+ return normalizeChatMessages([...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
34605
34951
  const aTime = a.message.receivedAt || a.message.timestamp || 0;
34606
34952
  const bTime = b2.message.receivedAt || b2.message.timestamp || 0;
34607
34953
  if (aTime !== bTime) return aTime - bTime;
34608
34954
  return a.index - b2.index;
34609
- }).map((entry) => entry.message);
34955
+ }).map((entry) => entry.message));
34610
34956
  }
34611
34957
  getPersistedEffectContent(effect) {
34612
34958
  if (effect.type === "message") {
@@ -35494,215 +35840,6 @@ ${effect.notification.body || ""}`.trim();
35494
35840
  }
35495
35841
  }
35496
35842
  init_logger();
35497
- function normalizeInputEnvelope(input) {
35498
- const normalized = normalizeInputEnvelopePayload(input);
35499
- const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
35500
- return {
35501
- parts: normalized.parts,
35502
- textFallback,
35503
- ...normalized.metadata ? { metadata: normalized.metadata } : {}
35504
- };
35505
- }
35506
- function normalizeMessageParts(content) {
35507
- if (typeof content === "string") return [{ type: "text", text: content }];
35508
- if (!Array.isArray(content)) {
35509
- if (content && typeof content === "object" && typeof content.text === "string") {
35510
- return [{ type: "text", text: String(content.text) }];
35511
- }
35512
- return [];
35513
- }
35514
- const parts = [];
35515
- for (const raw of content) {
35516
- if (typeof raw === "string") {
35517
- parts.push({ type: "text", text: raw });
35518
- continue;
35519
- }
35520
- if (!raw || typeof raw !== "object") continue;
35521
- const part = normalizeMessagePartObject(raw);
35522
- if (part) parts.push(part);
35523
- }
35524
- return parts;
35525
- }
35526
- function flattenMessageParts(parts) {
35527
- return parts.map((part) => {
35528
- if (part.type === "text") return part.text;
35529
- if (part.type === "resource") return part.resource.text || "";
35530
- return "";
35531
- }).filter((value) => value.length > 0).join("\n");
35532
- }
35533
- function normalizeInputEnvelopePayload(input) {
35534
- if (typeof input === "string") {
35535
- return { parts: [{ type: "text", text: input }], textFallback: input };
35536
- }
35537
- if (!input || typeof input !== "object") {
35538
- return { parts: [], textFallback: "" };
35539
- }
35540
- const record2 = input;
35541
- const nestedInput = record2.input;
35542
- if (nestedInput && typeof nestedInput === "object") {
35543
- const nested = nestedInput;
35544
- return {
35545
- parts: normalizeInputParts(nested.parts ?? nested.prompt),
35546
- textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
35547
- metadata: normalizeInputMetadata(nested.metadata)
35548
- };
35549
- }
35550
- const directText = typeof record2.text === "string" ? record2.text : typeof record2.message === "string" ? record2.message : void 0;
35551
- if (directText !== void 0) {
35552
- return { parts: [{ type: "text", text: directText }], textFallback: directText };
35553
- }
35554
- const directParts = normalizeInputParts(record2.parts ?? record2.prompt);
35555
- return {
35556
- parts: directParts,
35557
- textFallback: typeof record2.textFallback === "string" ? record2.textFallback : void 0,
35558
- metadata: normalizeInputMetadata(record2.metadata)
35559
- };
35560
- }
35561
- function normalizeInputMetadata(value) {
35562
- if (!value || typeof value !== "object") return void 0;
35563
- const record2 = value;
35564
- const metadata = {};
35565
- if (record2.source === "dashboard" || record2.source === "shortcut_api" || record2.source === "provider_script" || record2.source === "session_replay") {
35566
- metadata.source = record2.source;
35567
- }
35568
- if (typeof record2.clientTimestamp === "number" && Number.isFinite(record2.clientTimestamp)) {
35569
- metadata.clientTimestamp = record2.clientTimestamp;
35570
- }
35571
- return Object.keys(metadata).length > 0 ? metadata : void 0;
35572
- }
35573
- function normalizeInputParts(value) {
35574
- if (!Array.isArray(value)) return [];
35575
- const parts = [];
35576
- for (const raw of value) {
35577
- if (typeof raw === "string") {
35578
- parts.push({ type: "text", text: raw });
35579
- continue;
35580
- }
35581
- if (!raw || typeof raw !== "object") continue;
35582
- const part = normalizeInputPartObject(raw);
35583
- if (part) parts.push(part);
35584
- }
35585
- return parts;
35586
- }
35587
- function normalizeInputPartObject(raw) {
35588
- const type = raw.type;
35589
- if (type === "text" && typeof raw.text === "string") {
35590
- return { type, text: raw.text };
35591
- }
35592
- if (type === "image" && typeof raw.mimeType === "string") {
35593
- return {
35594
- type,
35595
- mimeType: raw.mimeType,
35596
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35597
- ...typeof raw.data === "string" ? { data: raw.data } : {},
35598
- ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
35599
- };
35600
- }
35601
- if (type === "audio" && typeof raw.mimeType === "string") {
35602
- return {
35603
- type,
35604
- mimeType: raw.mimeType,
35605
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35606
- ...typeof raw.data === "string" ? { data: raw.data } : {},
35607
- ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
35608
- };
35609
- }
35610
- if (type === "video" && typeof raw.mimeType === "string") {
35611
- return {
35612
- type,
35613
- mimeType: raw.mimeType,
35614
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35615
- ...typeof raw.data === "string" ? { data: raw.data } : {},
35616
- ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
35617
- };
35618
- }
35619
- if (type === "resource" && typeof raw.uri === "string") {
35620
- return {
35621
- type,
35622
- uri: raw.uri,
35623
- ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
35624
- ...typeof raw.name === "string" ? { name: raw.name } : {},
35625
- ...typeof raw.text === "string" ? { text: raw.text } : {},
35626
- ...typeof raw.data === "string" ? { data: raw.data } : {}
35627
- };
35628
- }
35629
- if (type === "resource_link" && typeof raw.uri === "string") {
35630
- return {
35631
- type: "resource",
35632
- uri: raw.uri,
35633
- ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
35634
- ...typeof raw.name === "string" ? { name: raw.name } : {}
35635
- };
35636
- }
35637
- return null;
35638
- }
35639
- function normalizeMessagePartObject(raw) {
35640
- const type = raw.type;
35641
- if (type === "text" && typeof raw.text === "string") {
35642
- return { type, text: raw.text };
35643
- }
35644
- if (type === "image" && typeof raw.mimeType === "string") {
35645
- return {
35646
- type,
35647
- mimeType: raw.mimeType,
35648
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35649
- ...typeof raw.data === "string" ? { data: raw.data } : {}
35650
- };
35651
- }
35652
- if (type === "audio" && typeof raw.mimeType === "string") {
35653
- return {
35654
- type,
35655
- mimeType: raw.mimeType,
35656
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35657
- ...typeof raw.data === "string" ? { data: raw.data } : {},
35658
- ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
35659
- };
35660
- }
35661
- if (type === "video" && typeof raw.mimeType === "string") {
35662
- return {
35663
- type,
35664
- mimeType: raw.mimeType,
35665
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
35666
- ...typeof raw.data === "string" ? { data: raw.data } : {},
35667
- ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
35668
- };
35669
- }
35670
- if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
35671
- return {
35672
- type,
35673
- uri: raw.uri,
35674
- name: raw.name,
35675
- ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
35676
- ...typeof raw.size === "number" ? { size: raw.size } : {}
35677
- };
35678
- }
35679
- if (type === "resource" && raw.resource && typeof raw.resource === "object") {
35680
- const resource = raw.resource;
35681
- if (typeof resource.uri !== "string") return null;
35682
- return {
35683
- type,
35684
- resource: {
35685
- uri: resource.uri,
35686
- ...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
35687
- ...typeof resource.text === "string" ? { text: resource.text } : {},
35688
- ...typeof resource.blob === "string" ? { blob: resource.blob } : {}
35689
- }
35690
- };
35691
- }
35692
- return null;
35693
- }
35694
- function flattenInputParts(parts) {
35695
- return parts.map((part) => {
35696
- if (part.type === "text") return part.text;
35697
- if (part.type === "audio") return part.transcript || "";
35698
- if (part.type === "resource") return part.text || "";
35699
- return "";
35700
- }).filter((value) => value.length > 0).join("\n");
35701
- }
35702
- function flattenContent(content) {
35703
- if (typeof content === "string") return content;
35704
- return flattenMessageParts(normalizeMessageParts(content));
35705
- }
35706
35843
  init_logger();
35707
35844
  var NORMAL_TRACE_BUFFER_SIZE = 200;
35708
35845
  var DEV_TRACE_BUFFER_SIZE = 1e3;
@@ -35826,6 +35963,7 @@ ${effect.notification.body || ""}`.trim();
35826
35963
  function createInteractionId(prefix = "ix") {
35827
35964
  return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
35828
35965
  }
35966
+ init_chat_message_normalization();
35829
35967
  var RECENT_SEND_WINDOW_MS = 1200;
35830
35968
  var recentSendByTarget = /* @__PURE__ */ new Map();
35831
35969
  function hashSignatureParts2(parts) {
@@ -35955,7 +36093,7 @@ ${effect.notification.body || ""}`.trim();
35955
36093
  }
35956
36094
  function normalizeReadChatMessages(payload) {
35957
36095
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
35958
- return messages;
36096
+ return normalizeChatMessages(messages);
35959
36097
  }
35960
36098
  function deriveHistoryDedupKey(message) {
35961
36099
  const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
@@ -38285,6 +38423,7 @@ ${effect.notification.body || ""}`.trim();
38285
38423
  var import_node_module = require("module");
38286
38424
  init_provider_cli_adapter();
38287
38425
  init_logger();
38426
+ init_chat_message_normalization();
38288
38427
  var CachedDatabaseSync = null;
38289
38428
  function getDatabaseSync() {
38290
38429
  if (CachedDatabaseSync) return CachedDatabaseSync;
@@ -38779,8 +38918,8 @@ ${effect.notification.body || ""}`.trim();
38779
38918
  if (this.appliedEffectKeys.has(effectKey)) continue;
38780
38919
  this.appliedEffectKeys.add(effectKey);
38781
38920
  if (effect.persist !== false) {
38782
- const persisted = this.getPersistedEffectContent(effect);
38783
- if (persisted) this.appendRuntimeSystemMessage(persisted, effectKey);
38921
+ const persistedMessage = buildPersistedProviderEffectMessage(effect);
38922
+ if (persistedMessage) this.appendRuntimeMessage(persistedMessage, effectKey);
38784
38923
  }
38785
38924
  if (effect.type === "message" && effect.message) {
38786
38925
  const content = typeof effect.message.content === "string" ? effect.message.content : JSON.stringify(effect.message.content);
@@ -38904,44 +39043,53 @@ ${effect.notification.body || ""}`.trim();
38904
39043
  );
38905
39044
  }
38906
39045
  appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
38907
- const normalizedContent = String(content || "").trim();
38908
- if (!normalizedContent) return;
39046
+ this.appendRuntimeMessage(buildRuntimeSystemChatMessage({
39047
+ content,
39048
+ receivedAt,
39049
+ timestamp: receivedAt
39050
+ }), dedupKey);
39051
+ }
39052
+ appendRuntimeMessage(message, dedupKey) {
39053
+ const normalizedMessage = buildChatMessage({
39054
+ ...message,
39055
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp || Date.now(),
39056
+ timestamp: typeof message.timestamp === "number" ? message.timestamp : message.receivedAt || Date.now()
39057
+ });
39058
+ const normalizedContent = typeof normalizedMessage.content === "string" ? normalizedMessage.content.trim() : flattenContent(normalizedMessage.content).trim();
39059
+ if (!normalizedContent && (!Array.isArray(normalizedMessage.content) || normalizedMessage.content.length === 0)) return;
38909
39060
  if (this.runtimeMessages.some((entry) => entry.key === dedupKey)) return;
38910
39061
  this.runtimeMessages.push({
38911
39062
  key: dedupKey,
38912
- message: {
38913
- role: "system",
38914
- senderName: "System",
38915
- content: normalizedContent,
38916
- receivedAt,
38917
- timestamp: receivedAt
38918
- }
39063
+ message: normalizedMessage
38919
39064
  });
38920
39065
  if (this.runtimeMessages.length > 50) {
38921
39066
  this.runtimeMessages = this.runtimeMessages.slice(-50);
38922
39067
  }
38923
- this.historyWriter.appendNewMessages(
38924
- this.type,
38925
- [{
38926
- role: "system",
38927
- senderName: "System",
38928
- content: normalizedContent,
38929
- receivedAt,
38930
- historyDedupKey: dedupKey
38931
- }],
38932
- this.adapter.getScriptParsedStatus?.()?.title || this.workingDir.split("/").filter(Boolean).pop() || "session",
38933
- this.instanceId,
38934
- this.providerSessionId
38935
- );
39068
+ if (normalizedContent) {
39069
+ this.historyWriter.appendNewMessages(
39070
+ this.type,
39071
+ [{
39072
+ role: normalizedMessage.role,
39073
+ senderName: normalizedMessage.senderName,
39074
+ kind: normalizedMessage.kind,
39075
+ content: normalizedContent,
39076
+ receivedAt: normalizedMessage.receivedAt || normalizedMessage.timestamp,
39077
+ historyDedupKey: dedupKey
39078
+ }],
39079
+ this.adapter.getScriptParsedStatus?.()?.title || this.workingDir.split("/").filter(Boolean).pop() || "session",
39080
+ this.instanceId,
39081
+ this.providerSessionId
39082
+ );
39083
+ }
38936
39084
  }
38937
39085
  mergeConversationMessages(parsedMessages) {
38938
- if (this.runtimeMessages.length === 0) return parsedMessages;
38939
- return [...parsedMessages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
39086
+ if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
39087
+ return normalizeChatMessages([...parsedMessages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b2) => {
38940
39088
  const aTime = a.message.receivedAt || a.message.timestamp || 0;
38941
39089
  const bTime = b2.message.receivedAt || b2.message.timestamp || 0;
38942
39090
  if (aTime !== bTime) return aTime - bTime;
38943
39091
  return a.index - b2.index;
38944
- }).map((entry) => entry.message);
39092
+ }).map((entry) => entry.message));
38945
39093
  }
38946
39094
  formatApprovalRequestMessage(modalMessage, buttons) {
38947
39095
  const lines = ["Approval requested"];
@@ -39010,6 +39158,7 @@ ${effect.notification.body || ""}`.trim();
39010
39158
  var import_stream = require("stream");
39011
39159
  var import_child_process5 = require("child_process");
39012
39160
  var import_sdk = (init_acp(), __toCommonJS(acp_exports));
39161
+ init_chat_message_normalization();
39013
39162
  init_logger();
39014
39163
  function getPromptCapabilityFlags(agentCapabilities) {
39015
39164
  const prompt = agentCapabilities?.promptCapabilities || {};
@@ -39175,24 +39324,21 @@ ${effect.notification.body || ""}`.trim();
39175
39324
  }
39176
39325
  getState() {
39177
39326
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
39178
- const recentMessages = this.messages.slice(-50).map((m) => {
39327
+ const recentMessages = normalizeChatMessages(this.messages.slice(-50).map((m) => {
39179
39328
  const content = this.truncateContent(m.content);
39180
- return {
39181
- role: m.role,
39182
- content,
39183
- timestamp: m.timestamp,
39184
- toolCalls: m.toolCalls
39185
- };
39186
- });
39329
+ return buildChatMessage({
39330
+ ...m,
39331
+ content
39332
+ });
39333
+ }));
39187
39334
  if (this.currentStatus === "generating" && (this.partialContent || this.partialBlocks.length > 0)) {
39188
39335
  const blocks = this.buildPartialBlocks();
39189
39336
  if (blocks.length > 0) {
39190
- recentMessages.push({
39191
- role: "assistant",
39337
+ recentMessages.push(buildAssistantChatMessage({
39192
39338
  content: blocks,
39193
39339
  timestamp: Date.now(),
39194
39340
  toolCalls: this.turnToolCalls.length > 0 ? [...this.turnToolCalls] : void 0
39195
- });
39341
+ }));
39196
39342
  }
39197
39343
  }
39198
39344
  return {
@@ -39205,7 +39351,7 @@ ${effect.notification.body || ""}`.trim();
39205
39351
  id: this.sessionId || `${this.type}_${this.workingDir}`,
39206
39352
  title: `${this.provider.name} \xB7 ${dirName}`,
39207
39353
  status: this.currentStatus,
39208
- messages: recentMessages,
39354
+ messages: normalizeChatMessages(recentMessages),
39209
39355
  activeModal: this.currentStatus === "waiting_approval" ? {
39210
39356
  message: this.activeToolCalls.find((t) => t.status === "running")?.name || "Permission requested",
39211
39357
  buttons: ["Approve", "Reject"]
@@ -39737,11 +39883,10 @@ ${effect.notification.body || ""}`.trim();
39737
39883
  if (b2.type === "resource") return { type: "resource", resource: b2.resource };
39738
39884
  return { type: "text", text: flattenContent([b2]) };
39739
39885
  }) : [{ type: "text", text }];
39740
- this.messages.push({
39741
- role: "user",
39886
+ this.messages.push(buildUserChatMessage({
39742
39887
  content: contentBlocks && contentBlocks.length > 0 ? contentBlocks : text,
39743
39888
  timestamp: Date.now()
39744
- });
39889
+ }));
39745
39890
  this.currentStatus = "generating";
39746
39891
  this.partialContent = "";
39747
39892
  this.partialBlocks = [];
@@ -39911,11 +40056,11 @@ ${effect.notification.body || ""}`.trim();
39911
40056
  content = m.content.filter((p) => p.type === "text").map((p) => p.text || "").join("\n");
39912
40057
  }
39913
40058
  if (content.trim()) {
39914
- this.messages.push({
40059
+ this.messages.push(buildChatMessage({
39915
40060
  role: m.role || "assistant",
39916
40061
  content: content.trim(),
39917
40062
  timestamp: Date.now()
39918
- });
40063
+ }));
39919
40064
  this.partialContent = "";
39920
40065
  }
39921
40066
  }
@@ -39991,12 +40136,11 @@ ${effect.notification.body || ""}`.trim();
39991
40136
  return b2;
39992
40137
  }).filter((b2) => b2.type !== "text" || b2.type === "text" && b2.text.trim());
39993
40138
  if (finalBlocks.length > 0) {
39994
- this.messages.push({
39995
- role: "assistant",
40139
+ this.messages.push(buildAssistantChatMessage({
39996
40140
  content: finalBlocks.length === 1 && finalBlocks[0].type === "text" ? finalBlocks[0].text : finalBlocks,
39997
40141
  timestamp: Date.now(),
39998
40142
  toolCalls: this.turnToolCalls.length > 0 ? [...this.turnToolCalls] : void 0
39999
- });
40143
+ }));
40000
40144
  }
40001
40145
  this.partialContent = "";
40002
40146
  this.partialBlocks = [];
@@ -40056,11 +40200,10 @@ ${effect.notification.body || ""}`.trim();
40056
40200
  appendSystemMessage(content, timestamp = Date.now()) {
40057
40201
  const normalizedContent = String(content || "").trim();
40058
40202
  if (!normalizedContent) return;
40059
- this.messages.push({
40060
- role: "system",
40203
+ this.messages.push(buildRuntimeSystemChatMessage({
40061
40204
  content: normalizedContent,
40062
40205
  timestamp
40063
- });
40206
+ }));
40064
40207
  if (this.messages.length > 200) {
40065
40208
  this.messages = this.messages.slice(-100);
40066
40209
  }
@@ -44689,6 +44832,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44689
44832
  }
44690
44833
  };
44691
44834
  init_logger();
44835
+ init_chat_message_normalization();
44692
44836
  var AgentStreamPoller = class {
44693
44837
  deps;
44694
44838
  timer = null;
@@ -44844,12 +44988,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
44844
44988
  type: "message",
44845
44989
  id: effectId,
44846
44990
  persist: true,
44847
- message: {
44848
- role: "system",
44849
- senderName: "System",
44850
- kind: "system",
44991
+ message: buildRuntimeSystemChatMessage({
44851
44992
  content: formatAutoApprovalMessage(stream.activeModal?.message, buttonLabel)
44852
- }
44993
+ })
44853
44994
  }
44854
44995
  ]
44855
44996
  };
@@ -45091,6 +45232,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
45091
45232
  this.eventListeners = [];
45092
45233
  }
45093
45234
  };
45235
+ init_chat_message_normalization();
45094
45236
  var fs10 = __toESM2(require("fs"));
45095
45237
  var path18 = __toESM2(require("path"));
45096
45238
  var os18 = __toESM2(require("os"));