@adhdev/daemon-core 0.9.82-rc.185 → 0.9.82-rc.187
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/commands/mesh-coordinator.d.ts +13 -0
- package/dist/config/chat-history.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +21088 -20535
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6601 -6047
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/beads-db.d.ts +1 -0
- package/dist/mesh/mesh-events.d.ts +46 -1
- package/dist/mesh/mesh-work-queue.d.ts +1 -0
- package/dist/providers/contracts.d.ts +1 -1
- package/dist/providers/native-history/dispatcher.d.ts +2 -0
- package/dist/providers/spec/cli-adapter.d.ts +1 -0
- package/dist/providers/spec/native-history-executor.d.ts +2 -0
- package/package.json +1 -1
- package/src/chat/subscription-updates.ts +6 -0
- package/src/commands/chat-commands.ts +182 -18
- package/src/commands/cli-manager.ts +4 -0
- package/src/commands/mesh-coordinator.ts +110 -5
- package/src/commands/router.ts +111 -17
- package/src/config/chat-history.ts +4 -0
- package/src/index.ts +1 -1
- package/src/mesh/beads-db.ts +4 -0
- package/src/mesh/mesh-events.ts +264 -4
- package/src/mesh/mesh-work-queue.ts +4 -0
- package/src/providers/cli-provider-instance.ts +12 -4
- package/src/providers/contracts.ts +1 -1
- package/src/providers/native-history/dispatcher.ts +126 -17
- package/src/providers/provider-loader.ts +4 -7
- package/src/providers/spec/cli-adapter.ts +32 -5
- package/src/providers/spec/evaluator.ts +11 -1
- package/src/providers/spec/native-history-executor.ts +93 -27
- package/src/providers/types/interactive-prompt.ts +13 -1
package/dist/mesh/beads-db.d.ts
CHANGED
|
@@ -68,5 +68,6 @@ export declare class BeadsDB {
|
|
|
68
68
|
}>;
|
|
69
69
|
updateDirectDispatchStatus(meshId: string, sessionId: string, status: 'acked' | 'completed' | 'failed' | 'stale'): void;
|
|
70
70
|
cleanupTerminalDirectDispatches(olderThanMs: number): void;
|
|
71
|
+
deleteDirectDispatches(meshId: string): void;
|
|
71
72
|
markStaleDirectDispatches(meshId: string, olderThanMs: number): void;
|
|
72
73
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DaemonComponents } from '../boot/daemon-lifecycle.js';
|
|
2
|
+
import type { MeshLedgerKind } from './mesh-ledger.js';
|
|
2
3
|
export declare function __resetIdleAutoFastForwardForTests(): void;
|
|
3
4
|
export interface PendingMeshCoordinatorEvent {
|
|
4
5
|
event: string;
|
|
@@ -23,12 +24,56 @@ export declare function drainPendingMeshCoordinatorEvents(meshId?: string, coord
|
|
|
23
24
|
export declare function getPendingMeshCoordinatorEvents(meshId?: string, coordinatorDaemonId?: string): readonly PendingMeshCoordinatorEvent[];
|
|
24
25
|
/** Explicitly clear all pending coordinator events for a mesh (and coordinator if scoped). */
|
|
25
26
|
export declare function clearPendingMeshCoordinatorEvents(meshId?: string, coordinatorDaemonId?: string): void;
|
|
27
|
+
export declare function reconcileDirectDispatchCompletionFromTranscript(args: {
|
|
28
|
+
meshId: string;
|
|
29
|
+
nodeId?: string;
|
|
30
|
+
sessionId: string;
|
|
31
|
+
providerType?: string;
|
|
32
|
+
providerSessionId?: string;
|
|
33
|
+
taskId: string;
|
|
34
|
+
finalSummary: string;
|
|
35
|
+
transcriptMessageAt?: string;
|
|
36
|
+
completedAt?: string;
|
|
37
|
+
targetCoordinatorDaemonId?: string;
|
|
38
|
+
source?: string;
|
|
39
|
+
}): {
|
|
40
|
+
reconciled: boolean;
|
|
41
|
+
kind?: MeshLedgerKind;
|
|
42
|
+
alreadyTerminal?: boolean;
|
|
43
|
+
workerResult?: unknown;
|
|
44
|
+
ledgerEntryId?: string;
|
|
45
|
+
reason?: string;
|
|
46
|
+
};
|
|
26
47
|
export declare function tryAssignQueueTask(components: DaemonComponents, meshId: string, nodeId: string, sessionId: string, providerType: string): boolean;
|
|
48
|
+
export interface MeshQueueTriggerResult {
|
|
49
|
+
success: true;
|
|
50
|
+
meshId: string;
|
|
51
|
+
pendingBefore: number;
|
|
52
|
+
assignedBefore: number;
|
|
53
|
+
pendingAfter: number;
|
|
54
|
+
assignedAfter: number;
|
|
55
|
+
claimed: boolean;
|
|
56
|
+
newlyAssignedTasks: Array<{
|
|
57
|
+
id: string;
|
|
58
|
+
nodeId?: string;
|
|
59
|
+
sessionId?: string;
|
|
60
|
+
}>;
|
|
61
|
+
localIdleSessionsChecked: number;
|
|
62
|
+
remoteIdleSessionsChecked: number;
|
|
63
|
+
skippedSessions: Array<{
|
|
64
|
+
nodeId?: string;
|
|
65
|
+
sessionId?: string;
|
|
66
|
+
reason: string;
|
|
67
|
+
status?: string;
|
|
68
|
+
}>;
|
|
69
|
+
autoLaunchStarted: boolean;
|
|
70
|
+
noIdleMeshSessionAvailable?: boolean;
|
|
71
|
+
}
|
|
27
72
|
/**
|
|
28
73
|
* Triggers a queue check for all nodes in the mesh.
|
|
29
74
|
* Called when a new task is enqueued, in case nodes are already idle.
|
|
30
75
|
*/
|
|
31
|
-
export declare function triggerMeshQueue(components: DaemonComponents, meshId: string): Promise<
|
|
76
|
+
export declare function triggerMeshQueue(components: DaemonComponents, meshId: string): Promise<MeshQueueTriggerResult>;
|
|
32
77
|
export declare function handleMeshForwardEvent(components: DaemonComponents, payload: Record<string, unknown>): {
|
|
33
78
|
success: boolean;
|
|
34
79
|
forwarded: number;
|
|
@@ -136,6 +136,7 @@ export interface MeshWorkQueueStats {
|
|
|
136
136
|
export declare function getMeshQueueStats(meshId: string): MeshWorkQueueStats;
|
|
137
137
|
export declare function __replaceMeshQueueForTests(meshId: string, queue: MeshWorkQueueEntry[]): void;
|
|
138
138
|
export declare function __clearMeshQueueForTests(meshId: string): void;
|
|
139
|
+
export declare function __clearDirectDispatchesForTests(meshId: string): void;
|
|
139
140
|
export declare function __resetBeadsDBForTests(): void;
|
|
140
141
|
export type DirectDispatchRecord = ReturnType<BeadsDB['getActiveDirectDispatches']>[number];
|
|
141
142
|
export declare function insertDirectDispatch(meshId: string, data: {
|
|
@@ -302,7 +302,7 @@ export interface ProviderMeshCoordinatorConfig {
|
|
|
302
302
|
requiresRestart?: boolean;
|
|
303
303
|
/** User-facing setup explanation for manual modes. */
|
|
304
304
|
instructions?: string;
|
|
305
|
-
/** Copyable setup template. Supports {{meshId}}, {{adhdevMcpCommand}}, {{workspace}}, {{serverName}}. */
|
|
305
|
+
/** Copyable setup template. Supports {{meshId}}, {{adhdevMcpCommand}}, {{adhdevMcpArgs}}, {{workspace}}, {{serverName}}. */
|
|
306
306
|
template?: string;
|
|
307
307
|
};
|
|
308
308
|
/**
|
|
@@ -5,6 +5,7 @@ export interface NativeHistoryInput {
|
|
|
5
5
|
providerSessionId?: string;
|
|
6
6
|
historySessionId?: string;
|
|
7
7
|
workspace?: string;
|
|
8
|
+
sessionStartedAtMs?: number;
|
|
8
9
|
format?: string;
|
|
9
10
|
watchPath?: string;
|
|
10
11
|
forceRefresh?: boolean;
|
|
@@ -16,6 +17,7 @@ export interface NativeHistoryResult {
|
|
|
16
17
|
content: string;
|
|
17
18
|
receivedAt?: number;
|
|
18
19
|
kind?: string;
|
|
20
|
+
workspace?: string;
|
|
19
21
|
}>;
|
|
20
22
|
providerSessionId?: string;
|
|
21
23
|
sourcePath: string;
|
|
@@ -90,6 +90,7 @@ export declare class SpecCliAdapter implements CliAdapter {
|
|
|
90
90
|
private handleEvent;
|
|
91
91
|
private detectInteractivePromptFromPtyChunk;
|
|
92
92
|
private readCurrentScreenSections;
|
|
93
|
+
private extractProviderSessionIdFromScreen;
|
|
93
94
|
private readClaudeScreenAssistantMessages;
|
|
94
95
|
private maybeCaptureClaudeTuiPrompt;
|
|
95
96
|
private readClaudeTuiHeaders;
|
|
@@ -28,6 +28,7 @@ export interface NativeHistoryMessage {
|
|
|
28
28
|
content: string;
|
|
29
29
|
receivedAt: number;
|
|
30
30
|
kind?: string;
|
|
31
|
+
workspace?: string;
|
|
31
32
|
}
|
|
32
33
|
export interface NativeHistoryResult {
|
|
33
34
|
messages: NativeHistoryMessage[];
|
|
@@ -35,5 +36,6 @@ export interface NativeHistoryResult {
|
|
|
35
36
|
sourcePath: string;
|
|
36
37
|
sourceMtimeMs: number;
|
|
37
38
|
nativeHistoryCoverage?: 'full' | 'partial' | 'best-effort';
|
|
39
|
+
workspace?: string;
|
|
38
40
|
}
|
|
39
41
|
export declare function executeNativeHistory(cfg: NativeHistoryConfig, input: NativeHistoryInput): NativeHistoryResult | null;
|
package/package.json
CHANGED
|
@@ -110,6 +110,10 @@ export function prepareSessionChatTailUpdate(
|
|
|
110
110
|
const messages = fullMessages
|
|
111
111
|
const title = typeof result.title === 'string' ? result.title : undefined
|
|
112
112
|
const activeModal = normalizeChatTailActiveModal(result.activeModal)
|
|
113
|
+
const activeInteractivePrompt = (result as { activeInteractivePrompt?: unknown }).activeInteractivePrompt
|
|
114
|
+
const promptForUpdate = activeInteractivePrompt && typeof activeInteractivePrompt === 'object'
|
|
115
|
+
? activeInteractivePrompt as Record<string, unknown>
|
|
116
|
+
: null
|
|
113
117
|
const status = typeof result.status === 'string' ? result.status : 'idle'
|
|
114
118
|
// (A3) messageSource passthrough. v1 deliberately dropped this on the
|
|
115
119
|
// subscription wire so the frontend had to infer source from message
|
|
@@ -126,6 +130,7 @@ export function prepareSessionChatTailUpdate(
|
|
|
126
130
|
status,
|
|
127
131
|
...(title ? { title } : {}),
|
|
128
132
|
...(activeModal ? { activeModal } : {}),
|
|
133
|
+
...(promptForUpdate ? { activeInteractivePrompt: promptForUpdate } : {}),
|
|
129
134
|
})
|
|
130
135
|
const seq = input.seq + 1
|
|
131
136
|
|
|
@@ -154,6 +159,7 @@ export function prepareSessionChatTailUpdate(
|
|
|
154
159
|
status,
|
|
155
160
|
...(title ? { title } : {}),
|
|
156
161
|
...(activeModal ? { activeModal } : {}),
|
|
162
|
+
...(promptForUpdate ? { activeInteractivePrompt: promptForUpdate as any } : {}),
|
|
157
163
|
...(messageSource ? { messageSource } : {}),
|
|
158
164
|
},
|
|
159
165
|
}
|
|
@@ -222,6 +222,41 @@ function resolveCliNativeHistorySessionId(args: any, currentHistorySessionId: st
|
|
|
222
222
|
return current || parsed || undefined;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
function shouldSkipLiveCliNativeHistoryWithoutProviderSession(args: {
|
|
226
|
+
adapter?: CliAdapter | null;
|
|
227
|
+
providerType?: string;
|
|
228
|
+
readChatArgs: any;
|
|
229
|
+
nativeHistorySessionId?: string;
|
|
230
|
+
parsedProviderSessionId?: string;
|
|
231
|
+
}): boolean {
|
|
232
|
+
const explicit = getExplicitHistorySessionId(args.readChatArgs);
|
|
233
|
+
if (explicit) return false;
|
|
234
|
+
|
|
235
|
+
const targetSessionId = typeof args.readChatArgs?.targetSessionId === 'string'
|
|
236
|
+
? args.readChatArgs.targetSessionId.trim()
|
|
237
|
+
: '';
|
|
238
|
+
if (!targetSessionId) return false;
|
|
239
|
+
|
|
240
|
+
const resolved = typeof args.nativeHistorySessionId === 'string'
|
|
241
|
+
? args.nativeHistorySessionId.trim()
|
|
242
|
+
: '';
|
|
243
|
+
if (!resolved || resolved !== targetSessionId) return false;
|
|
244
|
+
|
|
245
|
+
const parsed = typeof args.parsedProviderSessionId === 'string'
|
|
246
|
+
? args.parsedProviderSessionId.trim()
|
|
247
|
+
: '';
|
|
248
|
+
if (parsed) return false;
|
|
249
|
+
|
|
250
|
+
const cliType = args.adapter?.cliType || args.providerType || '';
|
|
251
|
+
if (cliType !== 'codex-cli') return false;
|
|
252
|
+
|
|
253
|
+
// A live Codex session starts with only the daemon runtime UUID. That UUID
|
|
254
|
+
// is not the provider-native rollout id, so using it for native history
|
|
255
|
+
// lets the file picker fall back to the newest same-workspace transcript
|
|
256
|
+
// and makes concurrent fresh sessions all show the same old conversation.
|
|
257
|
+
return !!args.adapter;
|
|
258
|
+
}
|
|
259
|
+
|
|
225
260
|
function getInteractionId(args: any): string | undefined {
|
|
226
261
|
return typeof args?._interactionId === 'string' && args._interactionId.trim()
|
|
227
262
|
? args._interactionId.trim()
|
|
@@ -444,6 +479,7 @@ function normalizeNativeHistoryMessages(providerType: string, messages: ChatMess
|
|
|
444
479
|
...message,
|
|
445
480
|
role: role === 'human' ? 'user' : (role || 'assistant'),
|
|
446
481
|
kind: isSystemSessionStart ? 'system' : kind,
|
|
482
|
+
...(nativeIdentitySessionId ? { historySessionId: nativeIdentitySessionId } : {}),
|
|
447
483
|
providerUnitKey,
|
|
448
484
|
bubbleId: typeof message.bubbleId === 'string' && message.bubbleId.trim()
|
|
449
485
|
&& preserveNativeIdentity
|
|
@@ -604,6 +640,7 @@ function decideCliReadChatSource(args: {
|
|
|
604
640
|
nativeHistoryResult: any | null;
|
|
605
641
|
nativeHistoryError?: unknown;
|
|
606
642
|
safeMapping: boolean;
|
|
643
|
+
trustedExactNativeIdentity?: boolean;
|
|
607
644
|
sessionWorkspace?: string;
|
|
608
645
|
intendedWorkspace?: string;
|
|
609
646
|
ptyMessages: ChatMessage[];
|
|
@@ -617,7 +654,26 @@ function decideCliReadChatSource(args: {
|
|
|
617
654
|
const supportsNative = supportsCliNativeTranscript(args.providerType, args.provider);
|
|
618
655
|
const observation = buildObservationForCli(args, supportsNative);
|
|
619
656
|
const sessionKey = chatSourceSessionKey(args.providerType, args.sessionId);
|
|
620
|
-
|
|
657
|
+
let decision = CHAT_SOURCE_REGISTRY.observe(sessionKey, observation);
|
|
658
|
+
|
|
659
|
+
// A restored runtime can briefly expose different native slices while the
|
|
660
|
+
// provider transcript settles (for example, startup/system rows may be
|
|
661
|
+
// filtered after the first read). The source machine correctly treats a
|
|
662
|
+
// shrinking slice as regression, but an exact provider-session lookup with
|
|
663
|
+
// no PTY transcript has no safer fallback. Re-bootstrap only this proven
|
|
664
|
+
// identity so the chat does not disappear after daemon restart.
|
|
665
|
+
if (
|
|
666
|
+
decision.selected === 'pty-parser'
|
|
667
|
+
&& args.trustedExactNativeIdentity === true
|
|
668
|
+
&& args.safeMapping
|
|
669
|
+
&& args.ptyMessages.length === 0
|
|
670
|
+
&& observation.kind === 'native_present'
|
|
671
|
+
&& observation.coverage !== 'partial'
|
|
672
|
+
&& observation.messages.length > 0
|
|
673
|
+
) {
|
|
674
|
+
CHAT_SOURCE_REGISTRY.clear(sessionKey);
|
|
675
|
+
decision = CHAT_SOURCE_REGISTRY.observe(sessionKey, observation);
|
|
676
|
+
}
|
|
621
677
|
|
|
622
678
|
const nativeMessages: ChatMessage[] = observation.kind === 'native_present'
|
|
623
679
|
? extractNativeMessagesFromResult(args.providerType, args.nativeHistoryResult)
|
|
@@ -1034,6 +1090,17 @@ function hasSafeNativeHistoryMapping(args: {
|
|
|
1034
1090
|
|
|
1035
1091
|
const explicitSessionId = String(args.historySessionId || args.providerSessionId || '').trim();
|
|
1036
1092
|
if (explicitSessionId) {
|
|
1093
|
+
const expectedWorkspace = normalizeComparableWorkspace(args.workspace);
|
|
1094
|
+
const declaredWorkspaces = args.nativeMessages
|
|
1095
|
+
.map((message: any) => normalizeComparableWorkspace(message?.workspace))
|
|
1096
|
+
.filter(Boolean);
|
|
1097
|
+
if (
|
|
1098
|
+
expectedWorkspace
|
|
1099
|
+
&& declaredWorkspaces.length > 0
|
|
1100
|
+
&& !declaredWorkspaces.some((workspace) => workspace === expectedWorkspace)
|
|
1101
|
+
) {
|
|
1102
|
+
return false;
|
|
1103
|
+
}
|
|
1037
1104
|
const messageSessionIds = args.nativeMessages
|
|
1038
1105
|
.map((message: any) => typeof message?.historySessionId === 'string' ? message.historySessionId.trim() : '')
|
|
1039
1106
|
.filter(Boolean);
|
|
@@ -1128,7 +1195,12 @@ function readCliProviderNativeHistory(agentStr: string, args: {
|
|
|
1128
1195
|
sessionStartedAtMs?: number;
|
|
1129
1196
|
envOverrides?: Record<string, string>;
|
|
1130
1197
|
}): ReturnType<typeof readProviderChatHistory> & { lookup: 'session' | 'workspace' } {
|
|
1131
|
-
|
|
1198
|
+
const canBindFromLiveSession = !args.historySessionId
|
|
1199
|
+
&& typeof args.sessionStartedAtMs === 'number'
|
|
1200
|
+
&& args.sessionStartedAtMs > 0
|
|
1201
|
+
&& typeof args.workspace === 'string'
|
|
1202
|
+
&& args.workspace.trim().length > 0;
|
|
1203
|
+
if (!args.historySessionId && !canBindFromLiveSession) {
|
|
1132
1204
|
return {
|
|
1133
1205
|
messages: [],
|
|
1134
1206
|
hasMore: false,
|
|
@@ -1150,10 +1222,17 @@ function readCliProviderNativeHistory(agentStr: string, args: {
|
|
|
1150
1222
|
sessionStartedAtMs: args.sessionStartedAtMs,
|
|
1151
1223
|
envOverrides: args.envOverrides,
|
|
1152
1224
|
});
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1225
|
+
const boundProviderSessionId = typeof (sessionHistory as any)?.providerSessionId === 'string'
|
|
1226
|
+
? (sessionHistory as any).providerSessionId.trim()
|
|
1227
|
+
: '';
|
|
1228
|
+
// A fresh live session can be bound without a provider id when the native
|
|
1229
|
+
// reader matched both cwd and session_meta.timestamp to spawnedAtMs.
|
|
1230
|
+
return {
|
|
1231
|
+
...(sessionHistory as any),
|
|
1232
|
+
lookup: args.historySessionId || (canBindFromLiveSession && boundProviderSessionId)
|
|
1233
|
+
? 'session'
|
|
1234
|
+
: 'workspace',
|
|
1235
|
+
};
|
|
1157
1236
|
}
|
|
1158
1237
|
|
|
1159
1238
|
function readLiveCodexWorkspaceNativeHistory(agentStr: string, args: {
|
|
@@ -1613,8 +1692,10 @@ function summarizeStateForDebug(state: any): Record<string, unknown> | null {
|
|
|
1613
1692
|
title: activeChat.title,
|
|
1614
1693
|
messageCount: Array.isArray(activeChat.messages) ? activeChat.messages.length : undefined,
|
|
1615
1694
|
activeModal: activeChat.activeModal,
|
|
1695
|
+
activeInteractivePrompt: activeChat.activeInteractivePrompt ?? null,
|
|
1616
1696
|
messagesTail: Array.isArray(activeChat.messages) ? activeChat.messages.slice(-10) : undefined,
|
|
1617
1697
|
} : null,
|
|
1698
|
+
activeInteractivePrompt: (state as { activeInteractivePrompt?: unknown }).activeInteractivePrompt ?? null,
|
|
1618
1699
|
controlValues: state.controlValues,
|
|
1619
1700
|
summaryMetadata: state.summaryMetadata,
|
|
1620
1701
|
};
|
|
@@ -2115,11 +2196,21 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2115
2196
|
? resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId)
|
|
2116
2197
|
: undefined;
|
|
2117
2198
|
const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId.trim() : '';
|
|
2199
|
+
const skipLiveNativeHistoryWithoutProviderSession = shouldSkipLiveCliNativeHistoryWithoutProviderSession({
|
|
2200
|
+
adapter,
|
|
2201
|
+
providerType,
|
|
2202
|
+
readChatArgs: args,
|
|
2203
|
+
nativeHistorySessionId,
|
|
2204
|
+
parsedProviderSessionId: providerSessionId,
|
|
2205
|
+
});
|
|
2206
|
+
const nativeHistoryReadSessionId = skipLiveNativeHistoryWithoutProviderSession
|
|
2207
|
+
? undefined
|
|
2208
|
+
: nativeHistorySessionId;
|
|
2118
2209
|
const exactNativeHistoryScope = Boolean(
|
|
2119
2210
|
(typeof args?.historySessionId === 'string' && args.historySessionId.trim())
|
|
2120
2211
|
|| (typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
2121
2212
|
|| providerSessionId
|
|
2122
|
-
|| (
|
|
2213
|
+
|| (nativeHistoryReadSessionId && nativeHistoryReadSessionId !== targetSessionId)
|
|
2123
2214
|
|| ((h.currentSession as any)?.sessionId === args?.targetSessionId && typeof (h.currentSession as any)?.providerSessionId === 'string' && (h.currentSession as any).providerSessionId.trim())
|
|
2124
2215
|
);
|
|
2125
2216
|
|
|
@@ -2130,7 +2221,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2130
2221
|
try {
|
|
2131
2222
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
2132
2223
|
canonicalHistory: provider?.nativeHistory,
|
|
2133
|
-
historySessionId:
|
|
2224
|
+
historySessionId: nativeHistoryReadSessionId,
|
|
2134
2225
|
workspace,
|
|
2135
2226
|
offset: 0,
|
|
2136
2227
|
limit: nativeHistoryLimit,
|
|
@@ -2149,20 +2240,21 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2149
2240
|
|
|
2150
2241
|
// 2. Compute safeMapping with the same rules the v1 code used so the
|
|
2151
2242
|
// machine sees the same observation it always would have.
|
|
2152
|
-
|
|
2243
|
+
let nativeMessages: ChatMessage[] = nativeHistory && Array.isArray(nativeHistory.messages)
|
|
2153
2244
|
? normalizeAndFilterNativeHistory(h, agentStr, args, nativeHistory.messages as ChatMessage[], nativeHistory.providerSessionId)
|
|
2154
2245
|
: [];
|
|
2155
|
-
const
|
|
2246
|
+
const sessionStartedAtMs = sessionStartedAtMsFromRegistry(h, args?.targetSessionId);
|
|
2247
|
+
let historyProviderSessionId = typeof nativeHistory?.providerSessionId === 'string'
|
|
2156
2248
|
? nativeHistory.providerSessionId
|
|
2157
|
-
: readHistorySessionIdFromMessages(nativeMessages) ||
|
|
2158
|
-
|
|
2159
|
-
|
|
2249
|
+
: readHistorySessionIdFromMessages(nativeMessages) || nativeHistoryReadSessionId || historySessionId;
|
|
2250
|
+
let lookup = nativeHistory?.lookup === 'workspace' ? 'workspace' : 'session';
|
|
2251
|
+
let nativeHistorySessionForMapping = adapter.cliType === 'antigravity-cli'
|
|
2160
2252
|
&& historyProviderSessionId
|
|
2161
|
-
&&
|
|
2162
|
-
&& historyProviderSessionId !==
|
|
2253
|
+
&& nativeHistoryReadSessionId
|
|
2254
|
+
&& historyProviderSessionId !== nativeHistoryReadSessionId
|
|
2163
2255
|
? undefined
|
|
2164
|
-
:
|
|
2165
|
-
|
|
2256
|
+
: nativeHistoryReadSessionId;
|
|
2257
|
+
let safeMapping = supportsNative && nativeHistory
|
|
2166
2258
|
? hasSafeNativeHistoryMapping({
|
|
2167
2259
|
historySessionId: lookup === 'workspace' ? undefined : nativeHistorySessionForMapping,
|
|
2168
2260
|
providerSessionId: lookup === 'workspace' ? undefined : historyProviderSessionId || providerSessionId,
|
|
@@ -2172,6 +2264,64 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2172
2264
|
requireWorkspaceContentOverlap: lookup === 'workspace' && !exactNativeHistoryScope,
|
|
2173
2265
|
})
|
|
2174
2266
|
: false;
|
|
2267
|
+
if (skipLiveNativeHistoryWithoutProviderSession && (!safeMapping || returnedMessages.length === 0)) {
|
|
2268
|
+
nativeHistory = null;
|
|
2269
|
+
nativeMessages = [];
|
|
2270
|
+
historyProviderSessionId = undefined;
|
|
2271
|
+
lookup = 'session';
|
|
2272
|
+
safeMapping = false;
|
|
2273
|
+
}
|
|
2274
|
+
const mayRetryUnsafeAutoDetectedCodexSession = adapter.cliType === 'codex-cli'
|
|
2275
|
+
&& !getExplicitHistorySessionId(args)
|
|
2276
|
+
&& Boolean(sessionStartedAtMs && sessionStartedAtMs > 0)
|
|
2277
|
+
&& !skipLiveNativeHistoryWithoutProviderSession
|
|
2278
|
+
&& !safeMapping;
|
|
2279
|
+
if (mayRetryUnsafeAutoDetectedCodexSession) {
|
|
2280
|
+
try {
|
|
2281
|
+
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
2282
|
+
canonicalHistory: provider?.nativeHistory,
|
|
2283
|
+
historySessionId: undefined,
|
|
2284
|
+
workspace,
|
|
2285
|
+
offset: 0,
|
|
2286
|
+
limit: nativeHistoryLimit,
|
|
2287
|
+
excludeRecentCount: 0,
|
|
2288
|
+
historyBehavior: provider?.historyBehavior,
|
|
2289
|
+
scripts: provider?.scripts as any,
|
|
2290
|
+
excludeInProgressTurn: returnedStatus === 'waiting_approval',
|
|
2291
|
+
sessionStartedAtMs,
|
|
2292
|
+
envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
|
|
2293
|
+
});
|
|
2294
|
+
nativeHistoryError = undefined;
|
|
2295
|
+
nativeMessages = nativeHistory && Array.isArray(nativeHistory.messages)
|
|
2296
|
+
? normalizeAndFilterNativeHistory(h, agentStr, args, nativeHistory.messages as ChatMessage[], nativeHistory.providerSessionId)
|
|
2297
|
+
: [];
|
|
2298
|
+
historyProviderSessionId = typeof nativeHistory?.providerSessionId === 'string'
|
|
2299
|
+
? nativeHistory.providerSessionId
|
|
2300
|
+
: readHistorySessionIdFromMessages(nativeMessages);
|
|
2301
|
+
lookup = nativeHistory?.lookup === 'workspace' ? 'workspace' : 'session';
|
|
2302
|
+
nativeHistorySessionForMapping = undefined;
|
|
2303
|
+
safeMapping = supportsNative && nativeHistory
|
|
2304
|
+
? hasSafeNativeHistoryMapping({
|
|
2305
|
+
historySessionId: lookup === 'workspace' ? undefined : historyProviderSessionId,
|
|
2306
|
+
providerSessionId: lookup === 'workspace' ? undefined : historyProviderSessionId,
|
|
2307
|
+
workspace,
|
|
2308
|
+
nativeMessages,
|
|
2309
|
+
ptyMessages: returnedMessages,
|
|
2310
|
+
requireWorkspaceContentOverlap: lookup === 'workspace' && !exactNativeHistoryScope,
|
|
2311
|
+
})
|
|
2312
|
+
: false;
|
|
2313
|
+
} catch (error: any) {
|
|
2314
|
+
nativeHistoryError = error;
|
|
2315
|
+
nativeHistory = null;
|
|
2316
|
+
nativeMessages = [];
|
|
2317
|
+
historyProviderSessionId = undefined;
|
|
2318
|
+
safeMapping = false;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
const trustedExactNativeIdentity = lookup !== 'workspace'
|
|
2322
|
+
&& Boolean(nativeHistoryReadSessionId)
|
|
2323
|
+
&& Boolean(historyProviderSessionId)
|
|
2324
|
+
&& nativeHistoryReadSessionId === historyProviderSessionId;
|
|
2175
2325
|
|
|
2176
2326
|
// 3. Drive ChatSourceMachine — one observation per readChat call,
|
|
2177
2327
|
// keyed by (providerType, sessionKey-for-this-call). targetSessionId
|
|
@@ -2191,6 +2341,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2191
2341
|
nativeHistoryResult: nativeHistory,
|
|
2192
2342
|
nativeHistoryError,
|
|
2193
2343
|
safeMapping,
|
|
2344
|
+
trustedExactNativeIdentity,
|
|
2194
2345
|
sessionWorkspace,
|
|
2195
2346
|
intendedWorkspace,
|
|
2196
2347
|
ptyMessages: returnedMessages,
|
|
@@ -2205,6 +2356,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2205
2356
|
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
2206
2357
|
selectedTranscriptAuthority = 'provider';
|
|
2207
2358
|
selectedCoverage = nativeHistory?.hasMore ? 'tail' : 'full';
|
|
2359
|
+
if (selectedProviderSessionId && selectedProviderSessionId !== providerSessionId) {
|
|
2360
|
+
adapter.updateRuntimeMeta?.({ providerSessionId: selectedProviderSessionId });
|
|
2361
|
+
}
|
|
2208
2362
|
} else if (supportsNative) {
|
|
2209
2363
|
// Native not selected. Two preserved v1 fallbacks before settling
|
|
2210
2364
|
// on PTY: (a) Codex-only live workspace native probe; (b) unsafe-
|
|
@@ -2222,7 +2376,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2222
2376
|
&& liveCurrentRuntimePtySafe
|
|
2223
2377
|
&& !(typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
2224
2378
|
&& !(providerSessionId && providerSessionId.trim())
|
|
2225
|
-
&&
|
|
2379
|
+
&& !nativeHistoryReadSessionId
|
|
2380
|
+
&& (!historyProviderSessionId || historyProviderSessionId === nativeHistoryReadSessionId || historyProviderSessionId === historySessionId)
|
|
2381
|
+
&& !skipLiveNativeHistoryWithoutProviderSession;
|
|
2226
2382
|
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative
|
|
2227
2383
|
? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
2228
2384
|
canonicalHistory: provider?.nativeHistory,
|
|
@@ -2267,6 +2423,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2267
2423
|
selectedProviderSessionId = liveWorkspaceNativeProviderSessionId || providerSessionId;
|
|
2268
2424
|
selectedTranscriptAuthority = 'provider';
|
|
2269
2425
|
selectedCoverage = (liveWorkspaceNativeHistory as any).hasMore ? 'tail' : 'full';
|
|
2426
|
+
if (selectedProviderSessionId && selectedProviderSessionId !== providerSessionId) {
|
|
2427
|
+
adapter.updateRuntimeMeta?.({ providerSessionId: selectedProviderSessionId });
|
|
2428
|
+
}
|
|
2270
2429
|
messageSource = liveDecision.messageSource;
|
|
2271
2430
|
(messageSource as any).selectedDaemonSource = 'live-workspace-native-history';
|
|
2272
2431
|
(messageSource as any).runtimeMappingSafe = true;
|
|
@@ -2404,6 +2563,10 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2404
2563
|
nativeMessages: historyMessages,
|
|
2405
2564
|
})
|
|
2406
2565
|
: false;
|
|
2566
|
+
const trustedExactNativeIdentity = lookup !== 'workspace'
|
|
2567
|
+
&& Boolean(historySessionId)
|
|
2568
|
+
&& Boolean(historyProviderSessionId)
|
|
2569
|
+
&& historySessionId === historyProviderSessionId;
|
|
2407
2570
|
|
|
2408
2571
|
const machineSessionKey = String(
|
|
2409
2572
|
args?.targetSessionId
|
|
@@ -2418,6 +2581,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2418
2581
|
sessionId: machineSessionKey,
|
|
2419
2582
|
nativeHistoryResult: history,
|
|
2420
2583
|
safeMapping,
|
|
2584
|
+
trustedExactNativeIdentity,
|
|
2421
2585
|
sessionWorkspace: workspace,
|
|
2422
2586
|
intendedWorkspace,
|
|
2423
2587
|
ptyMessages: [],
|
|
@@ -1305,6 +1305,10 @@ export class DaemonCliManager {
|
|
|
1305
1305
|
} else {
|
|
1306
1306
|
await adapter.sendMessage(message);
|
|
1307
1307
|
}
|
|
1308
|
+
const targetInstance = this.deps.getInstanceManager()?.getInstance(key) as
|
|
1309
|
+
| { recordAcknowledgedUserInput?: (input: unknown) => void }
|
|
1310
|
+
| undefined;
|
|
1311
|
+
targetInstance?.recordAcknowledgedUserInput?.(input);
|
|
1308
1312
|
return {
|
|
1309
1313
|
success: true,
|
|
1310
1314
|
status: BUSY_AGENT_STATUSES.has(currentStatus) ? currentStatus : 'generating',
|