@adhdev/daemon-core 0.9.82-rc.69 → 0.9.82-rc.70
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/cli-adapters/provider-cli-adapter.d.ts +2 -0
- package/dist/cli-adapters/provider-cli-parse.d.ts +1 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/dist/index.js +87 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +91 -3
- package/src/cli-adapters/provider-cli-parse.d.ts +1 -0
- package/src/cli-adapters/provider-cli-parse.ts +4 -0
- package/src/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/src/cli-adapters/provider-cli-shared.ts +2 -0
- package/src/commands/handler.ts +8 -1
- package/src/config/chat-history.ts +9 -7
- package/src/daemon/dev-cli-debug.ts +10 -1
package/package.json
CHANGED
|
@@ -761,6 +761,17 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
761
761
|
if (stableMs < 2000) return;
|
|
762
762
|
|
|
763
763
|
const startupModal = this.runParseApproval(this.recentOutputBuffer);
|
|
764
|
+
const startupStatus = this.runDetectStatus(screenText || this.recentOutputBuffer);
|
|
765
|
+
if (!startupModal && startupStatus !== 'idle') {
|
|
766
|
+
this.recordTrace('startup_settle_deferred', {
|
|
767
|
+
trigger,
|
|
768
|
+
startupStatus,
|
|
769
|
+
stableMs,
|
|
770
|
+
screenText: summarizeCliTraceText(screenText, 500),
|
|
771
|
+
});
|
|
772
|
+
this.scheduleStartupSettleCheck();
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
764
775
|
this.startupParseGate = false;
|
|
765
776
|
if (this.startupSettleTimer) {
|
|
766
777
|
clearTimeout(this.startupSettleTimer);
|
|
@@ -956,6 +967,38 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
956
967
|
return true;
|
|
957
968
|
}
|
|
958
969
|
|
|
970
|
+
private clearParsedIdleResponseGuard(reason: string, parsedStatus: any): boolean {
|
|
971
|
+
const parsedRawStatus = typeof parsedStatus?.status === 'string' ? parsedStatus.status.trim() : '';
|
|
972
|
+
const parsedModal = parsedStatus?.activeModal ?? parsedStatus?.modal ?? null;
|
|
973
|
+
const blockingModal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
|
|
974
|
+
if (
|
|
975
|
+
!this.isWaitingForResponse
|
|
976
|
+
|| parsedRawStatus !== 'idle'
|
|
977
|
+
|| !!parsedModal
|
|
978
|
+
|| !!blockingModal
|
|
979
|
+
|| !this.parsedStatusHasFinalAssistantMessage(parsedStatus)
|
|
980
|
+
) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
this.clearAllTimers();
|
|
984
|
+
this.clearIdleFinishCandidate(reason);
|
|
985
|
+
this.responseBuffer = '';
|
|
986
|
+
this.isWaitingForResponse = false;
|
|
987
|
+
this.responseSettleIgnoreUntil = 0;
|
|
988
|
+
this.submitRetryUsed = false;
|
|
989
|
+
this.submitRetryPromptSnippet = '';
|
|
990
|
+
this.finishRetryCount = 0;
|
|
991
|
+
this.currentTurnScope = null;
|
|
992
|
+
this.activeModal = null;
|
|
993
|
+
this.setStatus('idle', reason);
|
|
994
|
+
this.recordTrace('parsed_idle_response_cleared', {
|
|
995
|
+
reason,
|
|
996
|
+
parsedStatus: parsedRawStatus,
|
|
997
|
+
parsedMessageCount: Array.isArray(parsedStatus?.messages) ? parsedStatus.messages.length : 0,
|
|
998
|
+
});
|
|
999
|
+
return true;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
959
1002
|
private hasMeaningfulResponseBuffer(promptSnippet: string): boolean {
|
|
960
1003
|
const raw = String(this.responseBuffer || '').trim();
|
|
961
1004
|
if (!raw) return false;
|
|
@@ -1489,6 +1532,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1489
1532
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1490
1533
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1491
1534
|
terminalScreenText: parseScreenText,
|
|
1535
|
+
workingDir: this.workingDir,
|
|
1492
1536
|
baseMessages: [],
|
|
1493
1537
|
partialResponse: this.responseBuffer,
|
|
1494
1538
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
@@ -1552,6 +1596,15 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1552
1596
|
return !!(startupModal || this.activeModal);
|
|
1553
1597
|
}
|
|
1554
1598
|
|
|
1599
|
+
private parsedStatusHasFinalAssistantMessage(parsed: any): boolean {
|
|
1600
|
+
const messages = Array.isArray(parsed?.messages) ? parsed.messages : [];
|
|
1601
|
+
const lastAssistant = [...messages].reverse().find((message: any) => {
|
|
1602
|
+
if (!message || message.role !== 'assistant') return false;
|
|
1603
|
+
return typeof message.content === 'string' && message.content.trim().length > 0;
|
|
1604
|
+
});
|
|
1605
|
+
return !!lastAssistant;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1555
1608
|
private projectEffectiveStatus(startupModal: { message: string; buttons: string[] } | null = null): CliSessionStatus['status'] {
|
|
1556
1609
|
if (this.parseErrorMessage) return 'error';
|
|
1557
1610
|
if (this.hasActionableApproval(startupModal)) return 'waiting_approval';
|
|
@@ -1564,8 +1617,14 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1564
1617
|
getStatus(options: { allowParse?: boolean } = {}): CliSessionStatus {
|
|
1565
1618
|
const allowParse = options.allowParse !== false;
|
|
1566
1619
|
const startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
1620
|
+
const startupDetectedStatus = allowParse && this.startupParseGate && !startupModal
|
|
1621
|
+
? this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText())
|
|
1622
|
+
: null;
|
|
1567
1623
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
1568
1624
|
let effectiveModal = startupModal || this.activeModal;
|
|
1625
|
+
if (startupDetectedStatus === 'waiting_approval') {
|
|
1626
|
+
effectiveStatus = 'waiting_approval';
|
|
1627
|
+
}
|
|
1569
1628
|
if (allowParse && !startupModal && !effectiveModal) {
|
|
1570
1629
|
const parsed = this.getFreshParsedStatusCache();
|
|
1571
1630
|
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons)
|
|
@@ -1575,6 +1634,18 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1575
1634
|
if (parsed?.status === 'waiting_approval' && parsedModal) {
|
|
1576
1635
|
effectiveStatus = 'waiting_approval';
|
|
1577
1636
|
effectiveModal = parsedModal;
|
|
1637
|
+
} else if (
|
|
1638
|
+
effectiveStatus === 'idle'
|
|
1639
|
+
&& parsed?.status === 'generating'
|
|
1640
|
+
&& !this.parsedStatusHasFinalAssistantMessage(parsed)
|
|
1641
|
+
) {
|
|
1642
|
+
effectiveStatus = 'generating';
|
|
1643
|
+
} else if (
|
|
1644
|
+
effectiveStatus === 'generating'
|
|
1645
|
+
&& parsed?.status === 'idle'
|
|
1646
|
+
&& this.parsedStatusHasFinalAssistantMessage(parsed)
|
|
1647
|
+
) {
|
|
1648
|
+
effectiveStatus = 'idle';
|
|
1578
1649
|
}
|
|
1579
1650
|
}
|
|
1580
1651
|
const bufferState = this.getBufferState();
|
|
@@ -1665,6 +1736,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1665
1736
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1666
1737
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1667
1738
|
terminalScreenText: this.getParseScreenText(this.terminalScreen.getText()),
|
|
1739
|
+
workingDir: this.workingDir,
|
|
1668
1740
|
baseMessages: [],
|
|
1669
1741
|
partialResponse: this.responseBuffer,
|
|
1670
1742
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
@@ -1979,7 +2051,10 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1979
2051
|
}
|
|
1980
2052
|
}
|
|
1981
2053
|
if (this.isWaitingForResponse && !allowInputDuringGeneration) {
|
|
1982
|
-
if (
|
|
2054
|
+
if (
|
|
2055
|
+
!this.clearStaleIdleResponseGuard('send_message_guard')
|
|
2056
|
+
&& !this.clearParsedIdleResponseGuard('send_message_parsed_idle_guard', parsedStatusBeforeSend)
|
|
2057
|
+
) {
|
|
1983
2058
|
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
1984
2059
|
}
|
|
1985
2060
|
}
|
|
@@ -2369,10 +2444,23 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
2369
2444
|
getDebugState(): Record<string, any> {
|
|
2370
2445
|
const screenText = sanitizeTerminalText(this.terminalScreen.getText());
|
|
2371
2446
|
const startupModal = this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
2372
|
-
const
|
|
2373
|
-
|
|
2447
|
+
const startupDetectedStatus = this.startupParseGate && !startupModal
|
|
2448
|
+
? this.runDetectStatus(this.recentOutputBuffer || screenText)
|
|
2449
|
+
: null;
|
|
2450
|
+
const effectiveReady = this.ready || !!startupModal || startupDetectedStatus === 'waiting_approval';
|
|
2374
2451
|
const parsedDebugState = this.getParsedDebugState();
|
|
2375
2452
|
const parsedMessages = Array.isArray(parsedDebugState?.messages) ? parsedDebugState.messages : [];
|
|
2453
|
+
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
2454
|
+
if (startupDetectedStatus === 'waiting_approval') {
|
|
2455
|
+
effectiveStatus = 'waiting_approval';
|
|
2456
|
+
}
|
|
2457
|
+
if (
|
|
2458
|
+
effectiveStatus === 'idle'
|
|
2459
|
+
&& parsedDebugState?.status === 'generating'
|
|
2460
|
+
&& !this.parsedStatusHasFinalAssistantMessage(parsedDebugState)
|
|
2461
|
+
) {
|
|
2462
|
+
effectiveStatus = 'generating';
|
|
2463
|
+
}
|
|
2376
2464
|
return {
|
|
2377
2465
|
type: this.cliType,
|
|
2378
2466
|
name: this.cliName,
|
|
@@ -15,6 +15,7 @@ export declare function buildCliParseInput(options: {
|
|
|
15
15
|
accumulatedRawBuffer: string;
|
|
16
16
|
recentOutputBuffer: string;
|
|
17
17
|
terminalScreenText: string;
|
|
18
|
+
workingDir?: string;
|
|
18
19
|
baseMessages: CliChatMessage[];
|
|
19
20
|
partialResponse: string;
|
|
20
21
|
isWaitingForResponse?: boolean;
|
|
@@ -35,6 +35,7 @@ export function buildCliParseInput(options: {
|
|
|
35
35
|
accumulatedRawBuffer: string;
|
|
36
36
|
recentOutputBuffer: string;
|
|
37
37
|
terminalScreenText: string;
|
|
38
|
+
workingDir?: string;
|
|
38
39
|
baseMessages: CliChatMessage[];
|
|
39
40
|
partialResponse: string;
|
|
40
41
|
isWaitingForResponse?: boolean;
|
|
@@ -46,6 +47,7 @@ export function buildCliParseInput(options: {
|
|
|
46
47
|
accumulatedRawBuffer,
|
|
47
48
|
recentOutputBuffer,
|
|
48
49
|
terminalScreenText,
|
|
50
|
+
workingDir,
|
|
49
51
|
baseMessages,
|
|
50
52
|
partialResponse,
|
|
51
53
|
isWaitingForResponse,
|
|
@@ -66,6 +68,8 @@ export function buildCliParseInput(options: {
|
|
|
66
68
|
rawBuffer,
|
|
67
69
|
recentBuffer,
|
|
68
70
|
screenText,
|
|
71
|
+
workspace: workingDir,
|
|
72
|
+
workingDir,
|
|
69
73
|
screen: buildCliScreenSnapshot(screenText),
|
|
70
74
|
bufferScreen: buildCliScreenSnapshot(buffer),
|
|
71
75
|
recentScreen: buildCliScreenSnapshot(recentBuffer),
|
package/src/commands/handler.ts
CHANGED
|
@@ -408,12 +408,19 @@ export class DaemonCommandHandler implements CommandHelpers {
|
|
|
408
408
|
'invoke_provider_script',
|
|
409
409
|
]);
|
|
410
410
|
|
|
411
|
+
// read_chat and get_chat_debug_bundle can serve historical transcript data even
|
|
412
|
+
// when the live session record is gone (stopped/destroyed). Allow the fallback
|
|
413
|
+
// when the provider type is known and any session identity hint is present:
|
|
414
|
+
// an explicit providerSessionId/historySessionId, or the targetSessionId itself
|
|
415
|
+
// (which getHistorySessionId already uses as a fallback history key).
|
|
416
|
+
const isReadOrDebugCmd = cmd === 'read_chat' || cmd === 'get_chat_debug_bundle';
|
|
411
417
|
const allowsInactiveReadChatFallback =
|
|
412
|
-
|
|
418
|
+
isReadOrDebugCmd
|
|
413
419
|
&& !!this._currentRoute.providerType
|
|
414
420
|
&& (
|
|
415
421
|
(typeof args?.providerSessionId === 'string' && args.providerSessionId.trim().length > 0)
|
|
416
422
|
|| (typeof args?.historySessionId === 'string' && args.historySessionId.trim().length > 0)
|
|
423
|
+
|| (typeof args?.targetSessionId === 'string' && args.targetSessionId.trim().length > 0)
|
|
417
424
|
);
|
|
418
425
|
|
|
419
426
|
if (this._currentRoute.sessionLookupFailed && sessionScopedCommands.has(cmd) && !allowsInactiveReadChatFallback) {
|
|
@@ -1387,22 +1387,23 @@ function callProviderNativeHistoryRead(
|
|
|
1387
1387
|
agentType: string,
|
|
1388
1388
|
canonicalHistory: ProviderCanonicalHistoryConfig | undefined,
|
|
1389
1389
|
scripts: ProviderNativeHistoryScripts | undefined,
|
|
1390
|
-
historySessionId: string,
|
|
1390
|
+
historySessionId: string | undefined,
|
|
1391
1391
|
workspace?: string,
|
|
1392
1392
|
): ProviderNativeHistoryReadResult | null {
|
|
1393
1393
|
const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, 'readSession');
|
|
1394
1394
|
if (!fn) return null;
|
|
1395
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || '');
|
|
1395
1396
|
const result = fn({
|
|
1396
1397
|
agentType,
|
|
1397
|
-
sessionId:
|
|
1398
|
-
historySessionId,
|
|
1398
|
+
sessionId: normalizedSessionId,
|
|
1399
|
+
historySessionId: normalizedSessionId,
|
|
1399
1400
|
workspace,
|
|
1400
1401
|
format: canonicalHistory?.format,
|
|
1401
1402
|
watchPath: canonicalHistory?.watchPath,
|
|
1402
|
-
args: { sessionId:
|
|
1403
|
+
args: { sessionId: normalizedSessionId, historySessionId: normalizedSessionId, workspace },
|
|
1403
1404
|
});
|
|
1404
1405
|
if (!result || typeof result !== 'object') return null;
|
|
1405
|
-
const records = normalizeProviderNativeHistoryRecords(agentType,
|
|
1406
|
+
const records = normalizeProviderNativeHistoryRecords(agentType, normalizedSessionId, (result as any).messages || (result as any).records);
|
|
1406
1407
|
if (records.length === 0) return null;
|
|
1407
1408
|
return {
|
|
1408
1409
|
records,
|
|
@@ -1419,7 +1420,8 @@ function buildNativeHistoryReadResult(
|
|
|
1419
1420
|
workspace?: string,
|
|
1420
1421
|
): ProviderNativeHistoryReadResult | null {
|
|
1421
1422
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || '');
|
|
1422
|
-
|
|
1423
|
+
const normalizedWorkspace = typeof workspace === 'string' ? workspace.trim() : '';
|
|
1424
|
+
if (!canonicalHistory || (!normalizedSessionId && !normalizedWorkspace) || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
|
|
1423
1425
|
return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
|
|
1424
1426
|
}
|
|
1425
1427
|
|
|
@@ -1478,7 +1480,7 @@ export function readProviderChatHistory(
|
|
|
1478
1480
|
scripts?: ProviderNativeHistoryScripts;
|
|
1479
1481
|
} = {},
|
|
1480
1482
|
): { messages: HistoryMessage[]; hasMore: boolean; source: 'provider-native' | 'adhdev-mirror' | 'native-unavailable'; sourcePath?: string; sourceMtimeMs?: number } {
|
|
1481
|
-
if (isNativeSourceCanonicalHistory(options.canonicalHistory) && options.historySessionId) {
|
|
1483
|
+
if (isNativeSourceCanonicalHistory(options.canonicalHistory) && (options.historySessionId || options.workspace)) {
|
|
1482
1484
|
const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace);
|
|
1483
1485
|
if (!nativeResult) return { messages: [], hasMore: false, source: 'native-unavailable' };
|
|
1484
1486
|
return {
|
|
@@ -802,7 +802,16 @@ export async function handleCliSend(ctx: DevServerContext, req: http.IncomingMes
|
|
|
802
802
|
}
|
|
803
803
|
|
|
804
804
|
try {
|
|
805
|
-
|
|
805
|
+
if (target.category === 'cli') {
|
|
806
|
+
const bundle = getCliTargetBundle(ctx, type, instanceId);
|
|
807
|
+
if (!bundle) {
|
|
808
|
+
ctx.json(res, 404, { error: `No running CLI adapter found for: ${type || instanceId}` });
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
await bundle.adapter.sendMessage(text);
|
|
812
|
+
} else {
|
|
813
|
+
ctx.instanceManager!.sendEvent(target.instanceId, 'send_message', { text });
|
|
814
|
+
}
|
|
806
815
|
ctx.json(res, 200, { sent: true, type: target.type, instanceId: target.instanceId });
|
|
807
816
|
} catch (e: any) {
|
|
808
817
|
ctx.json(res, 500, { error: `Send failed: ${e.message}` });
|