@adhdev/daemon-core 0.9.82-rc.186 → 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 +14604 -14063
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6591 -6049
- 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/commands/chat-commands.ts +180 -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/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
|
@@ -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: {
|
|
@@ -2117,11 +2196,21 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2117
2196
|
? resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId)
|
|
2118
2197
|
: undefined;
|
|
2119
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;
|
|
2120
2209
|
const exactNativeHistoryScope = Boolean(
|
|
2121
2210
|
(typeof args?.historySessionId === 'string' && args.historySessionId.trim())
|
|
2122
2211
|
|| (typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
2123
2212
|
|| providerSessionId
|
|
2124
|
-
|| (
|
|
2213
|
+
|| (nativeHistoryReadSessionId && nativeHistoryReadSessionId !== targetSessionId)
|
|
2125
2214
|
|| ((h.currentSession as any)?.sessionId === args?.targetSessionId && typeof (h.currentSession as any)?.providerSessionId === 'string' && (h.currentSession as any).providerSessionId.trim())
|
|
2126
2215
|
);
|
|
2127
2216
|
|
|
@@ -2132,7 +2221,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2132
2221
|
try {
|
|
2133
2222
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
2134
2223
|
canonicalHistory: provider?.nativeHistory,
|
|
2135
|
-
historySessionId:
|
|
2224
|
+
historySessionId: nativeHistoryReadSessionId,
|
|
2136
2225
|
workspace,
|
|
2137
2226
|
offset: 0,
|
|
2138
2227
|
limit: nativeHistoryLimit,
|
|
@@ -2151,20 +2240,21 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2151
2240
|
|
|
2152
2241
|
// 2. Compute safeMapping with the same rules the v1 code used so the
|
|
2153
2242
|
// machine sees the same observation it always would have.
|
|
2154
|
-
|
|
2243
|
+
let nativeMessages: ChatMessage[] = nativeHistory && Array.isArray(nativeHistory.messages)
|
|
2155
2244
|
? normalizeAndFilterNativeHistory(h, agentStr, args, nativeHistory.messages as ChatMessage[], nativeHistory.providerSessionId)
|
|
2156
2245
|
: [];
|
|
2157
|
-
const
|
|
2246
|
+
const sessionStartedAtMs = sessionStartedAtMsFromRegistry(h, args?.targetSessionId);
|
|
2247
|
+
let historyProviderSessionId = typeof nativeHistory?.providerSessionId === 'string'
|
|
2158
2248
|
? nativeHistory.providerSessionId
|
|
2159
|
-
: readHistorySessionIdFromMessages(nativeMessages) ||
|
|
2160
|
-
|
|
2161
|
-
|
|
2249
|
+
: readHistorySessionIdFromMessages(nativeMessages) || nativeHistoryReadSessionId || historySessionId;
|
|
2250
|
+
let lookup = nativeHistory?.lookup === 'workspace' ? 'workspace' : 'session';
|
|
2251
|
+
let nativeHistorySessionForMapping = adapter.cliType === 'antigravity-cli'
|
|
2162
2252
|
&& historyProviderSessionId
|
|
2163
|
-
&&
|
|
2164
|
-
&& historyProviderSessionId !==
|
|
2253
|
+
&& nativeHistoryReadSessionId
|
|
2254
|
+
&& historyProviderSessionId !== nativeHistoryReadSessionId
|
|
2165
2255
|
? undefined
|
|
2166
|
-
:
|
|
2167
|
-
|
|
2256
|
+
: nativeHistoryReadSessionId;
|
|
2257
|
+
let safeMapping = supportsNative && nativeHistory
|
|
2168
2258
|
? hasSafeNativeHistoryMapping({
|
|
2169
2259
|
historySessionId: lookup === 'workspace' ? undefined : nativeHistorySessionForMapping,
|
|
2170
2260
|
providerSessionId: lookup === 'workspace' ? undefined : historyProviderSessionId || providerSessionId,
|
|
@@ -2174,6 +2264,64 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2174
2264
|
requireWorkspaceContentOverlap: lookup === 'workspace' && !exactNativeHistoryScope,
|
|
2175
2265
|
})
|
|
2176
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;
|
|
2177
2325
|
|
|
2178
2326
|
// 3. Drive ChatSourceMachine — one observation per readChat call,
|
|
2179
2327
|
// keyed by (providerType, sessionKey-for-this-call). targetSessionId
|
|
@@ -2193,6 +2341,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2193
2341
|
nativeHistoryResult: nativeHistory,
|
|
2194
2342
|
nativeHistoryError,
|
|
2195
2343
|
safeMapping,
|
|
2344
|
+
trustedExactNativeIdentity,
|
|
2196
2345
|
sessionWorkspace,
|
|
2197
2346
|
intendedWorkspace,
|
|
2198
2347
|
ptyMessages: returnedMessages,
|
|
@@ -2207,6 +2356,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2207
2356
|
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
2208
2357
|
selectedTranscriptAuthority = 'provider';
|
|
2209
2358
|
selectedCoverage = nativeHistory?.hasMore ? 'tail' : 'full';
|
|
2359
|
+
if (selectedProviderSessionId && selectedProviderSessionId !== providerSessionId) {
|
|
2360
|
+
adapter.updateRuntimeMeta?.({ providerSessionId: selectedProviderSessionId });
|
|
2361
|
+
}
|
|
2210
2362
|
} else if (supportsNative) {
|
|
2211
2363
|
// Native not selected. Two preserved v1 fallbacks before settling
|
|
2212
2364
|
// on PTY: (a) Codex-only live workspace native probe; (b) unsafe-
|
|
@@ -2224,7 +2376,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2224
2376
|
&& liveCurrentRuntimePtySafe
|
|
2225
2377
|
&& !(typeof args?.providerSessionId === 'string' && args.providerSessionId.trim())
|
|
2226
2378
|
&& !(providerSessionId && providerSessionId.trim())
|
|
2227
|
-
&&
|
|
2379
|
+
&& !nativeHistoryReadSessionId
|
|
2380
|
+
&& (!historyProviderSessionId || historyProviderSessionId === nativeHistoryReadSessionId || historyProviderSessionId === historySessionId)
|
|
2381
|
+
&& !skipLiveNativeHistoryWithoutProviderSession;
|
|
2228
2382
|
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative
|
|
2229
2383
|
? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
2230
2384
|
canonicalHistory: provider?.nativeHistory,
|
|
@@ -2269,6 +2423,9 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2269
2423
|
selectedProviderSessionId = liveWorkspaceNativeProviderSessionId || providerSessionId;
|
|
2270
2424
|
selectedTranscriptAuthority = 'provider';
|
|
2271
2425
|
selectedCoverage = (liveWorkspaceNativeHistory as any).hasMore ? 'tail' : 'full';
|
|
2426
|
+
if (selectedProviderSessionId && selectedProviderSessionId !== providerSessionId) {
|
|
2427
|
+
adapter.updateRuntimeMeta?.({ providerSessionId: selectedProviderSessionId });
|
|
2428
|
+
}
|
|
2272
2429
|
messageSource = liveDecision.messageSource;
|
|
2273
2430
|
(messageSource as any).selectedDaemonSource = 'live-workspace-native-history';
|
|
2274
2431
|
(messageSource as any).runtimeMappingSafe = true;
|
|
@@ -2406,6 +2563,10 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2406
2563
|
nativeMessages: historyMessages,
|
|
2407
2564
|
})
|
|
2408
2565
|
: false;
|
|
2566
|
+
const trustedExactNativeIdentity = lookup !== 'workspace'
|
|
2567
|
+
&& Boolean(historySessionId)
|
|
2568
|
+
&& Boolean(historyProviderSessionId)
|
|
2569
|
+
&& historySessionId === historyProviderSessionId;
|
|
2409
2570
|
|
|
2410
2571
|
const machineSessionKey = String(
|
|
2411
2572
|
args?.targetSessionId
|
|
@@ -2420,6 +2581,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
|
|
|
2420
2581
|
sessionId: machineSessionKey,
|
|
2421
2582
|
nativeHistoryResult: history,
|
|
2422
2583
|
safeMapping,
|
|
2584
|
+
trustedExactNativeIdentity,
|
|
2423
2585
|
sessionWorkspace: workspace,
|
|
2424
2586
|
intendedWorkspace,
|
|
2425
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',
|