@adhdev/daemon-core 0.9.82-rc.90 → 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 +107 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +107 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/chat-commands.ts +119 -15
- package/src/mesh/mesh-active-work.ts +13 -1
- package/src/providers/chat-message-normalization.ts +4 -11
- package/src/providers/cli-provider-instance.ts +2 -1
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: {
|
|
@@ -396,6 +454,7 @@ function readCliProviderNativeHistory(agentStr: string, args: {
|
|
|
396
454
|
excludeRecentCount: number;
|
|
397
455
|
historyBehavior?: ProviderModule['historyBehavior'];
|
|
398
456
|
scripts?: ProviderScripts;
|
|
457
|
+
exactSessionScoped?: boolean;
|
|
399
458
|
}): ReturnType<typeof readProviderChatHistory> & { lookup: 'session' | 'workspace' } {
|
|
400
459
|
const sessionHistory = readProviderChatHistory(agentStr, {
|
|
401
460
|
canonicalHistory: args.canonicalHistory,
|
|
@@ -407,8 +466,12 @@ function readCliProviderNativeHistory(agentStr: string, args: {
|
|
|
407
466
|
historyBehavior: args.historyBehavior,
|
|
408
467
|
scripts: args.scripts as any,
|
|
409
468
|
});
|
|
410
|
-
|
|
411
|
-
|
|
469
|
+
// Exact runtime/provider transcript reads must not silently fall back to the
|
|
470
|
+
// workspace's active or most recent native transcript: multiple Hermes/Gemini/
|
|
471
|
+
// Codex sessions can run in the same workspace, and workspace fallback can make
|
|
472
|
+
// read_chat/completion evidence point at a different runtime's prompt.
|
|
473
|
+
if ((sessionHistory as any).source !== 'native-unavailable' || args.exactSessionScoped || !args.historySessionId || !args.workspace) {
|
|
474
|
+
return { ...(sessionHistory as any), lookup: args.historySessionId ? 'session' : 'workspace' };
|
|
412
475
|
}
|
|
413
476
|
const workspaceHistory = readProviderChatHistory(agentStr, {
|
|
414
477
|
canonicalHistory: args.canonicalHistory,
|
|
@@ -440,6 +503,22 @@ function shouldPreserveReadChatPayloadField(key: string): boolean {
|
|
|
440
503
|
return key === 'messageSource' || key === 'transcriptProvenance';
|
|
441
504
|
}
|
|
442
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
|
+
|
|
443
522
|
function deriveHistoryDedupKey(message: ChatMessage & { _unitKey?: string; _turnKey?: string }): string | undefined {
|
|
444
523
|
const unitKey = typeof message._unitKey === 'string' ? message._unitKey.trim() : '';
|
|
445
524
|
if (unitKey) return `read_chat:${unitKey}`;
|
|
@@ -589,6 +668,13 @@ function buildReadChatCommandResult(payload: Record<string, any>, args: any): Co
|
|
|
589
668
|
const visibleMessages = filterUserFacingChatMessages(messages);
|
|
590
669
|
const sync = buildFullTail(visibleMessages, normalizeReadChatTailLimit(args));
|
|
591
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
|
+
}
|
|
592
678
|
const returnedDebugReadChat = debugReadChat
|
|
593
679
|
? {
|
|
594
680
|
...debugReadChat,
|
|
@@ -603,7 +689,7 @@ function buildReadChatCommandResult(payload: Record<string, any>, args: any): Co
|
|
|
603
689
|
return {
|
|
604
690
|
success: true,
|
|
605
691
|
...validatedPayload,
|
|
606
|
-
...
|
|
692
|
+
...preservedPayloadFields,
|
|
607
693
|
messages: sync.messages,
|
|
608
694
|
totalMessages: sync.totalMessages,
|
|
609
695
|
...(returnedDebugReadChat ? { debugReadChat: returnedDebugReadChat } : {}),
|
|
@@ -1163,17 +1249,27 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1163
1249
|
returnedMessages.length,
|
|
1164
1250
|
200,
|
|
1165
1251
|
);
|
|
1252
|
+
const nativeHistorySessionId = resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId);
|
|
1253
|
+
const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId.trim() : '';
|
|
1254
|
+
const exactNativeHistoryScope = Boolean(
|
|
1255
|
+
(typeof args?.historySessionId === 'string' && args.historySessionId.trim())
|
|
1256
|
+
|| (typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
1257
|
+
|| providerSessionId
|
|
1258
|
+
|| (nativeHistorySessionId && nativeHistorySessionId !== targetSessionId)
|
|
1259
|
+
|| ((h.currentSession as any)?.sessionId === args?.targetSessionId && typeof (h.currentSession as any)?.providerSessionId === 'string' && (h.currentSession as any).providerSessionId.trim())
|
|
1260
|
+
);
|
|
1166
1261
|
let nativeHistory: (ReturnType<typeof readProviderChatHistory> & { lookup?: 'session' | 'workspace' }) | null = null;
|
|
1167
1262
|
try {
|
|
1168
1263
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
1169
1264
|
canonicalHistory: provider?.canonicalHistory,
|
|
1170
|
-
historySessionId,
|
|
1265
|
+
historySessionId: nativeHistorySessionId,
|
|
1171
1266
|
workspace,
|
|
1172
1267
|
offset: 0,
|
|
1173
1268
|
limit: nativeHistoryLimit,
|
|
1174
1269
|
excludeRecentCount: 0,
|
|
1175
1270
|
historyBehavior: provider?.historyBehavior,
|
|
1176
1271
|
scripts: provider?.scripts as any,
|
|
1272
|
+
exactSessionScoped: exactNativeHistoryScope,
|
|
1177
1273
|
});
|
|
1178
1274
|
} catch (error: any) {
|
|
1179
1275
|
const fallbackReason = `native_history_error:${error?.message || String(error)}`;
|
|
@@ -1194,13 +1290,15 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1194
1290
|
: [];
|
|
1195
1291
|
const historyProviderSessionId = typeof (nativeHistory as any)?.providerSessionId === 'string'
|
|
1196
1292
|
? (nativeHistory as any).providerSessionId
|
|
1197
|
-
: readHistorySessionIdFromMessages(nativeMessages) || historySessionId;
|
|
1293
|
+
: readHistorySessionIdFromMessages(nativeMessages) || nativeHistorySessionId || historySessionId;
|
|
1198
1294
|
const lookup = (nativeHistory as any).lookup === 'workspace' ? 'workspace' : 'session';
|
|
1199
1295
|
const safeMapping = hasSafeNativeHistoryMapping({
|
|
1200
|
-
historySessionId: lookup === 'workspace' ? undefined :
|
|
1201
|
-
providerSessionId: lookup === 'workspace' ? undefined : providerSessionId,
|
|
1296
|
+
historySessionId: lookup === 'workspace' ? undefined : nativeHistorySessionId,
|
|
1297
|
+
providerSessionId: lookup === 'workspace' ? undefined : historyProviderSessionId || providerSessionId,
|
|
1202
1298
|
workspace,
|
|
1203
1299
|
nativeMessages,
|
|
1300
|
+
ptyMessages: returnedMessages,
|
|
1301
|
+
requireWorkspaceContentOverlap: lookup === 'workspace' && !exactNativeHistoryScope,
|
|
1204
1302
|
});
|
|
1205
1303
|
const freshEnough = isNativeHistoryFreshEnough({
|
|
1206
1304
|
sourceMtimeMs: (nativeHistory as any).sourceMtimeMs,
|
|
@@ -1215,7 +1313,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1215
1313
|
messageSource = buildCliMessageSourceProvenance({
|
|
1216
1314
|
selected: 'native-history',
|
|
1217
1315
|
provider: adapter.cliType,
|
|
1218
|
-
nativeHandle: selectedProviderSessionId || historySessionId,
|
|
1316
|
+
nativeHandle: selectedProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
1219
1317
|
nativeSource: (nativeHistory as any).source,
|
|
1220
1318
|
sourcePath: (nativeHistory as any).sourcePath,
|
|
1221
1319
|
sourceMtimeMs: (nativeHistory as any).sourceMtimeMs,
|
|
@@ -1238,7 +1336,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1238
1336
|
messageSource = buildCliMessageSourceProvenance({
|
|
1239
1337
|
selected: 'pty-parser',
|
|
1240
1338
|
provider: adapter.cliType,
|
|
1241
|
-
nativeHandle: historyProviderSessionId || historySessionId,
|
|
1339
|
+
nativeHandle: historyProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
1242
1340
|
fallbackReason,
|
|
1243
1341
|
nativeSource: (nativeHistory as any).source,
|
|
1244
1342
|
sourcePath: (nativeHistory as any).sourcePath,
|
|
@@ -1286,6 +1384,11 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1286
1384
|
: typeof (h.currentSession as any)?.workspace === 'string'
|
|
1287
1385
|
? (h.currentSession as any).workspace
|
|
1288
1386
|
: undefined;
|
|
1387
|
+
const exactNativeHistoryScope = Boolean(
|
|
1388
|
+
(typeof args?.historySessionId === 'string' && args.historySessionId.trim())
|
|
1389
|
+
|| (typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
1390
|
+
|| ((h.currentSession as any)?.sessionId === args?.targetSessionId && typeof (h.currentSession as any)?.providerSessionId === 'string' && (h.currentSession as any).providerSessionId.trim())
|
|
1391
|
+
);
|
|
1289
1392
|
const history = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory)
|
|
1290
1393
|
? readCliProviderNativeHistory(agentStr, {
|
|
1291
1394
|
canonicalHistory: provider?.canonicalHistory,
|
|
@@ -1296,6 +1399,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
1296
1399
|
excludeRecentCount: 0,
|
|
1297
1400
|
historyBehavior: provider?.historyBehavior,
|
|
1298
1401
|
scripts: provider?.scripts as any,
|
|
1402
|
+
exactSessionScoped: exactNativeHistoryScope,
|
|
1299
1403
|
})
|
|
1300
1404
|
: readProviderChatHistory(agentStr, {
|
|
1301
1405
|
canonicalHistory: provider?.canonicalHistory,
|
|
@@ -80,7 +80,19 @@ function sessionStatusFromNodes(nodes: any[] | undefined, nodeId?: string, sessi
|
|
|
80
80
|
if (!node) return { staleReason: 'direct task node is no longer in the live mesh' };
|
|
81
81
|
if (!sessionId) return {};
|
|
82
82
|
const candidates: any[] = [];
|
|
83
|
-
for (const value of [
|
|
83
|
+
for (const value of [
|
|
84
|
+
node.sessions,
|
|
85
|
+
node.activeSessions,
|
|
86
|
+
node.active_sessions,
|
|
87
|
+
node.activeSessionDetails,
|
|
88
|
+
node.active_session_details,
|
|
89
|
+
node.sessionDetails,
|
|
90
|
+
node.session_details,
|
|
91
|
+
node.lastProbe?.sessions,
|
|
92
|
+
node.last_probe?.sessions,
|
|
93
|
+
node.lastProbe?.status?.sessions,
|
|
94
|
+
node.last_probe?.status?.sessions,
|
|
95
|
+
]) {
|
|
84
96
|
if (Array.isArray(value)) candidates.push(...value);
|
|
85
97
|
}
|
|
86
98
|
for (const value of [node.activeSession, node.active_session, node.currentSession, node.current_session, node.runtimeSession, node.runtime_session, node.session]) {
|
|
@@ -20,17 +20,10 @@ export function extractFinalSummaryFromMessages(
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const classification = classifyChatMessageVisibility(msg);
|
|
28
|
-
if (classification.isUserFacing) {
|
|
29
|
-
const text = flattenContent(msg.content).trim();
|
|
30
|
-
if (text) return text.slice(0, maxChars);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
23
|
+
// Completion summaries must describe the assistant/model result. If no
|
|
24
|
+
// user-facing assistant/model message exists yet (for example, only the
|
|
25
|
+
// dispatched user prompt is visible), return empty instead of echoing the
|
|
26
|
+
// prompt as a misleading finalSummary.
|
|
34
27
|
return '';
|
|
35
28
|
}
|
|
36
29
|
|
|
@@ -521,6 +521,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
521
521
|
}
|
|
522
522
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
523
523
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
524
|
+
const activeChatId = this.providerSessionId || runtime?.runtimeId || this.instanceId;
|
|
524
525
|
let parsedMessages = Array.isArray(parsedStatus?.messages)
|
|
525
526
|
? parsedStatus.messages
|
|
526
527
|
: [];
|
|
@@ -597,7 +598,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
597
598
|
status: visibleStatus,
|
|
598
599
|
mode: this.presentationMode,
|
|
599
600
|
activeChat: {
|
|
600
|
-
id:
|
|
601
|
+
id: activeChatId,
|
|
601
602
|
title: parsedStatus?.title || dirName,
|
|
602
603
|
status: activeChatStatus,
|
|
603
604
|
messages: mergedMessages,
|