@adhdev/daemon-core 0.9.82-rc.91 → 0.9.82-rc.92
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 +81 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +81 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/chat-commands.ts +99 -13
package/package.json
CHANGED
|
@@ -50,6 +50,16 @@ function getTargetedCliAdapter(h: CommandHelpers, args: any, providerType?: stri
|
|
|
50
50
|
return h.getCliAdapter(args?.targetSessionId || providerType || h.currentSession?.providerType || h.currentManagerKey);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
function getExplicitHistorySessionId(args: any): string | undefined {
|
|
54
|
+
const explicit = typeof args?.historySessionId === 'string' ? args.historySessionId.trim() : '';
|
|
55
|
+
if (explicit) return explicit;
|
|
56
|
+
|
|
57
|
+
const explicitProviderSessionId = typeof args?.providerSessionId === 'string' ? args.providerSessionId.trim() : '';
|
|
58
|
+
if (explicitProviderSessionId) return explicitProviderSessionId;
|
|
59
|
+
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
53
63
|
function getTargetInstance(h: CommandHelpers, args: any): ApprovalSelectableInstance | null {
|
|
54
64
|
const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId.trim() : '';
|
|
55
65
|
const sessionId = targetSessionId || h.currentSession?.sessionId || '';
|
|
@@ -141,16 +151,17 @@ async function waitOnceForFreshHermesCliStart(adapter: CliAdapter, log: (msg: st
|
|
|
141
151
|
}
|
|
142
152
|
|
|
143
153
|
function getHistorySessionId(h: CommandHelpers, args: any): string | undefined {
|
|
144
|
-
const explicit =
|
|
154
|
+
const explicit = getExplicitHistorySessionId(args);
|
|
145
155
|
if (explicit) return explicit;
|
|
146
156
|
|
|
147
|
-
const explicitProviderSessionId = typeof args?.providerSessionId === 'string' ? args.providerSessionId.trim() : '';
|
|
148
|
-
if (explicitProviderSessionId) return explicitProviderSessionId;
|
|
149
|
-
|
|
150
157
|
const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId.trim() : '';
|
|
151
158
|
if (!targetSessionId) return undefined;
|
|
152
159
|
|
|
153
|
-
const
|
|
160
|
+
const session = h.ctx.sessionRegistry?.get(targetSessionId) as any;
|
|
161
|
+
const registeredProviderSessionId = typeof session?.providerSessionId === 'string' ? session.providerSessionId.trim() : '';
|
|
162
|
+
if (registeredProviderSessionId) return registeredProviderSessionId;
|
|
163
|
+
|
|
164
|
+
const instance = getTargetInstance(h, args);
|
|
154
165
|
const state = instance?.getState?.();
|
|
155
166
|
const providerSessionId = typeof state?.providerSessionId === 'string' ? state.providerSessionId.trim() : '';
|
|
156
167
|
if (providerSessionId) return providerSessionId;
|
|
@@ -166,6 +177,23 @@ function getHistorySessionId(h: CommandHelpers, args: any): string | undefined {
|
|
|
166
177
|
return targetSessionId;
|
|
167
178
|
}
|
|
168
179
|
|
|
180
|
+
function resolveCliNativeHistorySessionId(args: any, currentHistorySessionId: string | undefined, parsedProviderSessionId: string | undefined): string | undefined {
|
|
181
|
+
const explicit = getExplicitHistorySessionId(args);
|
|
182
|
+
if (explicit) return explicit;
|
|
183
|
+
|
|
184
|
+
const parsed = typeof parsedProviderSessionId === 'string' ? parsedProviderSessionId.trim() : '';
|
|
185
|
+
const current = typeof currentHistorySessionId === 'string' ? currentHistorySessionId.trim() : '';
|
|
186
|
+
const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId.trim() : '';
|
|
187
|
+
|
|
188
|
+
// getHistorySessionId falls back to the runtime session id when no native
|
|
189
|
+
// handle has been registered yet. For live CLI adapters the parser may
|
|
190
|
+
// already know the provider-native handle; prefer it over the runtime id so
|
|
191
|
+
// exact native reads do not miss the worker transcript and fall back to PTY
|
|
192
|
+
// or same-workspace history.
|
|
193
|
+
if (parsed && (!current || current === targetSessionId)) return parsed;
|
|
194
|
+
return current || parsed || undefined;
|
|
195
|
+
}
|
|
196
|
+
|
|
169
197
|
function getInteractionId(args: any): string | undefined {
|
|
170
198
|
return typeof args?._interactionId === 'string' && args._interactionId.trim()
|
|
171
199
|
? args._interactionId.trim()
|
|
@@ -368,11 +396,38 @@ function supportsCliNativeTranscript(providerType: string, provider?: ProviderMo
|
|
|
368
396
|
return provider?.category === 'cli' && isNativeSourceCanonicalHistory(provider?.canonicalHistory);
|
|
369
397
|
}
|
|
370
398
|
|
|
399
|
+
function getComparableVisibleText(message: ChatMessage | undefined): string {
|
|
400
|
+
if (!message) return '';
|
|
401
|
+
const role = String((message as any).role || '').trim().toLowerCase();
|
|
402
|
+
if (role !== 'user' && role !== 'assistant') return '';
|
|
403
|
+
const kind = String((message as any).kind || 'standard').trim().toLowerCase();
|
|
404
|
+
if (kind && kind !== 'standard') return '';
|
|
405
|
+
const content = flattenContent((message as any).content).replace(/\s+/g, ' ').trim();
|
|
406
|
+
return content;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function hasOverlappingVisibleConversationText(nativeMessages: ChatMessage[], ptyMessages: ChatMessage[]): boolean {
|
|
410
|
+
const nativeTexts = nativeMessages.map(getComparableVisibleText).filter(Boolean);
|
|
411
|
+
const ptyTexts = ptyMessages.map(getComparableVisibleText).filter(Boolean);
|
|
412
|
+
if (nativeTexts.length === 0 || ptyTexts.length === 0) return false;
|
|
413
|
+
for (const nativeText of nativeTexts) {
|
|
414
|
+
for (const ptyText of ptyTexts) {
|
|
415
|
+
if (nativeText === ptyText) return true;
|
|
416
|
+
const shorter = nativeText.length <= ptyText.length ? nativeText : ptyText;
|
|
417
|
+
const longer = nativeText.length <= ptyText.length ? ptyText : nativeText;
|
|
418
|
+
if (shorter.length >= 32 && longer.includes(shorter)) return true;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
|
|
371
424
|
function hasSafeNativeHistoryMapping(args: {
|
|
372
425
|
historySessionId?: string;
|
|
373
426
|
providerSessionId?: string;
|
|
374
427
|
workspace?: string;
|
|
375
428
|
nativeMessages: ChatMessage[];
|
|
429
|
+
ptyMessages?: ChatMessage[];
|
|
430
|
+
requireWorkspaceContentOverlap?: boolean;
|
|
376
431
|
}): boolean {
|
|
377
432
|
const explicitSessionId = String(args.historySessionId || args.providerSessionId || '').trim();
|
|
378
433
|
if (explicitSessionId) {
|
|
@@ -384,7 +439,10 @@ function hasSafeNativeHistoryMapping(args: {
|
|
|
384
439
|
}
|
|
385
440
|
const workspace = String(args.workspace || '').trim();
|
|
386
441
|
if (!workspace) return false;
|
|
387
|
-
|
|
442
|
+
const workspaceMatches = args.nativeMessages.some((message: any) => String(message?.workspace || '').trim() === workspace);
|
|
443
|
+
if (!workspaceMatches) return false;
|
|
444
|
+
if (!args.requireWorkspaceContentOverlap) return true;
|
|
445
|
+
return hasOverlappingVisibleConversationText(args.nativeMessages, args.ptyMessages || []);
|
|
388
446
|
}
|
|
389
447
|
|
|
390
448
|
function readCliProviderNativeHistory(agentStr: string, args: {
|
|
@@ -445,6 +503,22 @@ function shouldPreserveReadChatPayloadField(key: string): boolean {
|
|
|
445
503
|
return key === 'messageSource' || key === 'transcriptProvenance';
|
|
446
504
|
}
|
|
447
505
|
|
|
506
|
+
function updateMessageSourceReturnedCount(value: unknown, returnedMessageCount: number): unknown {
|
|
507
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return value;
|
|
508
|
+
const record = value as Record<string, unknown>;
|
|
509
|
+
const coverage = record.coverage && typeof record.coverage === 'object' && !Array.isArray(record.coverage)
|
|
510
|
+
? record.coverage as Record<string, unknown>
|
|
511
|
+
: undefined;
|
|
512
|
+
if (!coverage) return value;
|
|
513
|
+
return {
|
|
514
|
+
...record,
|
|
515
|
+
coverage: {
|
|
516
|
+
...coverage,
|
|
517
|
+
returnedMessageCount,
|
|
518
|
+
},
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
|
|
448
522
|
function deriveHistoryDedupKey(message: ChatMessage & { _unitKey?: string; _turnKey?: string }): string | undefined {
|
|
449
523
|
const unitKey = typeof message._unitKey === 'string' ? message._unitKey.trim() : '';
|
|
450
524
|
if (unitKey) return `read_chat:${unitKey}`;
|
|
@@ -594,6 +668,13 @@ function buildReadChatCommandResult(payload: Record<string, any>, args: any): Co
|
|
|
594
668
|
const visibleMessages = filterUserFacingChatMessages(messages);
|
|
595
669
|
const sync = buildFullTail(visibleMessages, normalizeReadChatTailLimit(args));
|
|
596
670
|
const hiddenMsgCount = Math.max(0, messages.length - visibleMessages.length);
|
|
671
|
+
const preservedPayloadFields = Object.fromEntries(Object.entries(payload).filter(([key]) => shouldPreserveReadChatPayloadField(key)));
|
|
672
|
+
if (preservedPayloadFields.messageSource) {
|
|
673
|
+
preservedPayloadFields.messageSource = updateMessageSourceReturnedCount(preservedPayloadFields.messageSource, sync.messages.length);
|
|
674
|
+
}
|
|
675
|
+
if (preservedPayloadFields.transcriptProvenance) {
|
|
676
|
+
preservedPayloadFields.transcriptProvenance = updateMessageSourceReturnedCount(preservedPayloadFields.transcriptProvenance, sync.messages.length);
|
|
677
|
+
}
|
|
597
678
|
const returnedDebugReadChat = debugReadChat
|
|
598
679
|
? {
|
|
599
680
|
...debugReadChat,
|
|
@@ -608,7 +689,7 @@ function buildReadChatCommandResult(payload: Record<string, any>, args: any): Co
|
|
|
608
689
|
return {
|
|
609
690
|
success: true,
|
|
610
691
|
...validatedPayload,
|
|
611
|
-
...
|
|
692
|
+
...preservedPayloadFields,
|
|
612
693
|
messages: sync.messages,
|
|
613
694
|
totalMessages: sync.totalMessages,
|
|
614
695
|
...(returnedDebugReadChat ? { debugReadChat: returnedDebugReadChat } : {}),
|
|
@@ -1168,17 +1249,20 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1168
1249
|
returnedMessages.length,
|
|
1169
1250
|
200,
|
|
1170
1251
|
);
|
|
1252
|
+
const nativeHistorySessionId = resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId);
|
|
1253
|
+
const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId.trim() : '';
|
|
1171
1254
|
const exactNativeHistoryScope = Boolean(
|
|
1172
1255
|
(typeof args?.historySessionId === 'string' && args.historySessionId.trim())
|
|
1173
1256
|
|| (typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
1174
1257
|
|| providerSessionId
|
|
1258
|
+
|| (nativeHistorySessionId && nativeHistorySessionId !== targetSessionId)
|
|
1175
1259
|
|| ((h.currentSession as any)?.sessionId === args?.targetSessionId && typeof (h.currentSession as any)?.providerSessionId === 'string' && (h.currentSession as any).providerSessionId.trim())
|
|
1176
1260
|
);
|
|
1177
1261
|
let nativeHistory: (ReturnType<typeof readProviderChatHistory> & { lookup?: 'session' | 'workspace' }) | null = null;
|
|
1178
1262
|
try {
|
|
1179
1263
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
1180
1264
|
canonicalHistory: provider?.canonicalHistory,
|
|
1181
|
-
historySessionId,
|
|
1265
|
+
historySessionId: nativeHistorySessionId,
|
|
1182
1266
|
workspace,
|
|
1183
1267
|
offset: 0,
|
|
1184
1268
|
limit: nativeHistoryLimit,
|
|
@@ -1206,13 +1290,15 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1206
1290
|
: [];
|
|
1207
1291
|
const historyProviderSessionId = typeof (nativeHistory as any)?.providerSessionId === 'string'
|
|
1208
1292
|
? (nativeHistory as any).providerSessionId
|
|
1209
|
-
: readHistorySessionIdFromMessages(nativeMessages) || historySessionId;
|
|
1293
|
+
: readHistorySessionIdFromMessages(nativeMessages) || nativeHistorySessionId || historySessionId;
|
|
1210
1294
|
const lookup = (nativeHistory as any).lookup === 'workspace' ? 'workspace' : 'session';
|
|
1211
1295
|
const safeMapping = hasSafeNativeHistoryMapping({
|
|
1212
|
-
historySessionId: lookup === 'workspace' ? undefined :
|
|
1213
|
-
providerSessionId: lookup === 'workspace' ? undefined : providerSessionId,
|
|
1296
|
+
historySessionId: lookup === 'workspace' ? undefined : nativeHistorySessionId,
|
|
1297
|
+
providerSessionId: lookup === 'workspace' ? undefined : historyProviderSessionId || providerSessionId,
|
|
1214
1298
|
workspace,
|
|
1215
1299
|
nativeMessages,
|
|
1300
|
+
ptyMessages: returnedMessages,
|
|
1301
|
+
requireWorkspaceContentOverlap: lookup === 'workspace' && !exactNativeHistoryScope,
|
|
1216
1302
|
});
|
|
1217
1303
|
const freshEnough = isNativeHistoryFreshEnough({
|
|
1218
1304
|
sourceMtimeMs: (nativeHistory as any).sourceMtimeMs,
|
|
@@ -1227,7 +1313,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1227
1313
|
messageSource = buildCliMessageSourceProvenance({
|
|
1228
1314
|
selected: 'native-history',
|
|
1229
1315
|
provider: adapter.cliType,
|
|
1230
|
-
nativeHandle: selectedProviderSessionId || historySessionId,
|
|
1316
|
+
nativeHandle: selectedProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
1231
1317
|
nativeSource: (nativeHistory as any).source,
|
|
1232
1318
|
sourcePath: (nativeHistory as any).sourcePath,
|
|
1233
1319
|
sourceMtimeMs: (nativeHistory as any).sourceMtimeMs,
|
|
@@ -1250,7 +1336,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1250
1336
|
messageSource = buildCliMessageSourceProvenance({
|
|
1251
1337
|
selected: 'pty-parser',
|
|
1252
1338
|
provider: adapter.cliType,
|
|
1253
|
-
nativeHandle: historyProviderSessionId || historySessionId,
|
|
1339
|
+
nativeHandle: historyProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
1254
1340
|
fallbackReason,
|
|
1255
1341
|
nativeSource: (nativeHistory as any).source,
|
|
1256
1342
|
sourcePath: (nativeHistory as any).sourcePath,
|