@adhdev/daemon-core 0.9.82-rc.255 → 0.9.82-rc.257
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 +15 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/mesh/mesh-events-coordinator.ts +17 -2
- package/src/providers/cli-provider-instance.ts +25 -29
package/package.json
CHANGED
|
@@ -1541,8 +1541,23 @@ export function setupMeshEventForwarding(components: DaemonComponents) {
|
|
|
1541
1541
|
|
|
1542
1542
|
const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor) || meshIdFromDirectDispatch;
|
|
1543
1543
|
|
|
1544
|
-
|
|
1545
|
-
|
|
1544
|
+
// A mesh worker must be recognised as a delegate even if its meshNodeFor stamp is
|
|
1545
|
+
// missing. Worker launch envelopes are assembled from several settings, and in
|
|
1546
|
+
// practice a worker can arrive carrying only meshCoordinatorDaemonId (the routing
|
|
1547
|
+
// anchor) without meshNodeFor — e.g. when the node/mesh stamp was dropped on a
|
|
1548
|
+
// direct dispatch or a relaunch. Gating delegate routing solely on meshNodeFor then
|
|
1549
|
+
// silently drops the completion: setupMeshEventForwarding returns here, the
|
|
1550
|
+
// coordinator filter can't resolve args.meshId, and the event only lands in the
|
|
1551
|
+
// pending queue that an idle/generating coordinator never drains. Treat any of the
|
|
1552
|
+
// worker-envelope markers as proof of delegation and recover the mesh id by
|
|
1553
|
+
// workspace when the runtime id is absent.
|
|
1554
|
+
const hasWorkerEnvelope = Boolean(
|
|
1555
|
+
meshIdFromRuntime
|
|
1556
|
+
|| settings.launchedByCoordinator
|
|
1557
|
+
|| readNonEmptyString(settings.meshCoordinatorDaemonId)
|
|
1558
|
+
|| readNonEmptyString(settings.meshCoordinatorNodeId),
|
|
1559
|
+
);
|
|
1560
|
+
if (!hasWorkerEnvelope) return;
|
|
1546
1561
|
|
|
1547
1562
|
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getCachedMeshByWorkspace(workspace);
|
|
1548
1563
|
const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
|
|
@@ -1088,8 +1088,31 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
1088
1088
|
}
|
|
1089
1089
|
|
|
1090
1090
|
private completionFinalSummary(parsedMessages: unknown): string | undefined {
|
|
1091
|
-
|
|
1092
|
-
|
|
1091
|
+
// For native-source providers (claude-cli: chatMessagesOwnedExternally), the PTY
|
|
1092
|
+
// screen parse is NOT the source of truth for the final summary — the terminal
|
|
1093
|
+
// wraps/scrolls/clips text, so a screen-parsed assistant message is often a partial
|
|
1094
|
+
// prefix (e.g. 76 chars of a 112-char turn). The append-only native transcript holds
|
|
1095
|
+
// the complete turn. Prefer it whenever it yields a longer/complete summary; fall back
|
|
1096
|
+
// to the parsed screen only when the transcript is unavailable. This is the real cause
|
|
1097
|
+
// of the truncated finalSummary — independent of cloud vs standalone (it surfaces on
|
|
1098
|
+
// any short, fast-completing task where screen parse wins the race).
|
|
1099
|
+
const adapterOwnsMessagesElsewhere = (this.adapter as any)?.chatMessagesOwnedExternally === true;
|
|
1100
|
+
const parsedSummary = extractFinalSummaryFromMessages(
|
|
1101
|
+
(this.completionHasFinalAssistantMessage(parsedMessages)
|
|
1102
|
+
? (Array.isArray(parsedMessages) ? parsedMessages : [])
|
|
1103
|
+
: []) as any,
|
|
1104
|
+
);
|
|
1105
|
+
if (adapterOwnsMessagesElsewhere) {
|
|
1106
|
+
const externalMessages = this.readExternalCompletionMessages();
|
|
1107
|
+
const externalSummary = externalMessages
|
|
1108
|
+
? extractFinalSummaryFromMessages(externalMessages as any)
|
|
1109
|
+
: '';
|
|
1110
|
+
// The transcript is authoritative for native-source providers. Use it unless it is
|
|
1111
|
+
// empty (not yet written) — only then fall back to whatever the screen parsed.
|
|
1112
|
+
if (externalSummary) return externalSummary;
|
|
1113
|
+
return parsedSummary || undefined;
|
|
1114
|
+
}
|
|
1115
|
+
return parsedSummary || undefined;
|
|
1093
1116
|
}
|
|
1094
1117
|
|
|
1095
1118
|
private buildCompletedFinalizationDiagnostic(args: {
|
|
@@ -1214,33 +1237,6 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
1214
1237
|
const adapterOwnsMessagesElsewhere = (this.adapter as any)?.chatMessagesOwnedExternally === true;
|
|
1215
1238
|
const finalAssistantEvidence = this.completionFinalAssistantEvidence(parsed?.messages);
|
|
1216
1239
|
const allowMissingAssistantTimeout = !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.launchedByCoordinator);
|
|
1217
|
-
|
|
1218
|
-
// Transcript settle guard: even when a final assistant message is present, a
|
|
1219
|
-
// native-source transcript the CLI is still appending to (the final assistant turn
|
|
1220
|
-
// lands in chunks) yields a *partial* finalSummary if read mid-flush — e.g. a 77-char
|
|
1221
|
-
// prefix "...base 8e788950, and". Re-read the transcript and compare against the prior
|
|
1222
|
-
// probe: if the last assistant message is still growing (msgCount or contentLen
|
|
1223
|
-
// increased since the previous probe), it is mid-write — block and retry. Once two
|
|
1224
|
-
// consecutive probes agree, the turn is fully flushed and we finalize. This keys on
|
|
1225
|
-
// observed growth, not wall-clock age, so an already-settled transcript finalizes with
|
|
1226
|
-
// no added latency. Matters most for worktree workers (cwd → a different projects/
|
|
1227
|
-
// folder than the primary checkout, where flush timing skews the read).
|
|
1228
|
-
if (adapterOwnsMessagesElsewhere && finalAssistantEvidence.source === 'external-native') {
|
|
1229
|
-
const prevProbe = (pending.transcriptProbeHistory || [])[ (pending.transcriptProbeHistory?.length ?? 0) - 1 ];
|
|
1230
|
-
this.readExternalCompletionMessages();
|
|
1231
|
-
const settleProbe = this.lastExternalCompletionProbe;
|
|
1232
|
-
if (settleProbe && prevProbe) {
|
|
1233
|
-
const stillGrowing = settleProbe.msgCount > prevProbe.msgCount
|
|
1234
|
-
|| (settleProbe.lastRole === 'assistant' && settleProbe.contentLen > prevProbe.contentLen);
|
|
1235
|
-
if (stillGrowing) {
|
|
1236
|
-
this.recordPendingTranscriptProbe(pending);
|
|
1237
|
-
return { reason: `transcript_settling:${prevProbe.contentLen}->${settleProbe.contentLen}`, terminal: false };
|
|
1238
|
-
}
|
|
1239
|
-
} else if (settleProbe) {
|
|
1240
|
-
// First observation: record a baseline so the next flush attempt can detect growth.
|
|
1241
|
-
this.recordPendingTranscriptProbe(pending);
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
1240
|
LOG.debug('CLI', `[${this.type}] finalAssistantEvidence: present=${finalAssistantEvidence.present} source=${finalAssistantEvidence.source} adapterOwnsMessagesElsewhere=${adapterOwnsMessagesElsewhere} parsedStatus=${parsedStatus}`);
|
|
1245
1241
|
if (!finalAssistantEvidence.present) {
|
|
1246
1242
|
if (adapterOwnsMessagesElsewhere) {
|