@adhdev/daemon-core 0.9.82-rc.56 → 0.9.82-rc.58
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 +73 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +73 -11
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +1 -0
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-runtime.ts +3 -1
- package/src/commands/router.ts +8 -8
- package/src/mesh/mesh-events.ts +14 -0
- package/src/providers/cli-provider-instance.ts +66 -1
|
@@ -101,6 +101,7 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
101
101
|
private completedDebouncePending;
|
|
102
102
|
private enforceFreshSessionLaunchIfNeeded;
|
|
103
103
|
private completionHasFinalAssistantMessage;
|
|
104
|
+
private buildCompletedFinalizationDiagnostic;
|
|
104
105
|
private hasAdapterPendingResponse;
|
|
105
106
|
private shouldSuppressStaleParsedBusyStatus;
|
|
106
107
|
private getCompletedFinalizationBlockReason;
|
package/package.json
CHANGED
|
@@ -36,7 +36,9 @@ export function resolveCliSpawnPlan(options: {
|
|
|
36
36
|
: spawnConfig.command;
|
|
37
37
|
const binaryPath = findBinary(configuredCommand);
|
|
38
38
|
const isWin = os.platform() === 'win32';
|
|
39
|
-
const allArgs = [...spawnConfig.args, ...extraArgs]
|
|
39
|
+
const allArgs = [...spawnConfig.args, ...extraArgs].map((arg) =>
|
|
40
|
+
typeof arg === 'string' ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg,
|
|
41
|
+
);
|
|
40
42
|
|
|
41
43
|
let shellCmd: string;
|
|
42
44
|
let shellArgs: string[];
|
package/src/commands/router.ts
CHANGED
|
@@ -460,16 +460,16 @@ function reconcileInlineMeshCache(cached: any, incoming: any): any {
|
|
|
460
460
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
461
461
|
if (!cachedNodes.length || !incomingNodes.length) return { ...cached, ...incoming };
|
|
462
462
|
|
|
463
|
-
const
|
|
464
|
-
for (const node of
|
|
463
|
+
const cachedById = new Map<string, any>();
|
|
464
|
+
for (const node of cachedNodes) {
|
|
465
465
|
const nodeId = readInlineMeshNodeId(node);
|
|
466
|
-
if (nodeId)
|
|
466
|
+
if (nodeId) cachedById.set(nodeId, node);
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
-
const nodes =
|
|
470
|
-
const nodeId = readInlineMeshNodeId(
|
|
471
|
-
const
|
|
472
|
-
if (!
|
|
469
|
+
const nodes = incomingNodes.map((incomingNode: any) => {
|
|
470
|
+
const nodeId = readInlineMeshNodeId(incomingNode);
|
|
471
|
+
const cachedNode = nodeId ? cachedById.get(nodeId) : undefined;
|
|
472
|
+
if (!cachedNode) return incomingNode;
|
|
473
473
|
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
474
474
|
return { ...cachedNode, ...incomingNode };
|
|
475
475
|
}
|
|
@@ -673,7 +673,7 @@ async function hydrateInlineMeshDirectTruth(args: {
|
|
|
673
673
|
continue;
|
|
674
674
|
}
|
|
675
675
|
|
|
676
|
-
if (
|
|
676
|
+
if (fs.existsSync(workspace)) {
|
|
677
677
|
try {
|
|
678
678
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 10_000, refreshUpstream: true });
|
|
679
679
|
if (localGit?.isGitRepo) {
|
package/src/mesh/mesh-events.ts
CHANGED
|
@@ -135,10 +135,21 @@ function isMeshCoordinatorEvent(eventName: unknown): eventName is string {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
function formatCompletionMetadata(event: Record<string, unknown>): string {
|
|
138
|
+
const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === 'object'
|
|
139
|
+
? event.completionDiagnostic as Record<string, unknown>
|
|
140
|
+
: null;
|
|
141
|
+
const diagnosticReason = completionDiagnostic
|
|
142
|
+
? readNonEmptyString(completionDiagnostic.blockReason) || 'present'
|
|
143
|
+
: '';
|
|
144
|
+
const finalAssistantPresent = typeof completionDiagnostic?.finalAssistantPresent === 'boolean'
|
|
145
|
+
? String(completionDiagnostic.finalAssistantPresent)
|
|
146
|
+
: '';
|
|
138
147
|
const parts = [
|
|
139
148
|
readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : '',
|
|
140
149
|
readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : '',
|
|
141
150
|
readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : '',
|
|
151
|
+
diagnosticReason ? `completion_diagnostic=${diagnosticReason}` : '',
|
|
152
|
+
finalAssistantPresent ? `final_assistant=${finalAssistantPresent}` : '',
|
|
142
153
|
].filter(Boolean);
|
|
143
154
|
return parts.length > 0 ? ` (${parts.join('; ')})` : '';
|
|
144
155
|
}
|
|
@@ -836,6 +847,9 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
836
847
|
taskId: completedTaskForLedger?.id || undefined,
|
|
837
848
|
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || undefined,
|
|
838
849
|
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || undefined,
|
|
850
|
+
completionDiagnostic: args.metadataEvent.completionDiagnostic && typeof args.metadataEvent.completionDiagnostic === 'object'
|
|
851
|
+
? args.metadataEvent.completionDiagnostic
|
|
852
|
+
: undefined,
|
|
839
853
|
evidence: completionEvidence,
|
|
840
854
|
},
|
|
841
855
|
});
|
|
@@ -743,6 +743,55 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
743
743
|
return role === 'assistant' && !!content;
|
|
744
744
|
}
|
|
745
745
|
|
|
746
|
+
private buildCompletedFinalizationDiagnostic(args: {
|
|
747
|
+
blockReason: string;
|
|
748
|
+
latestStatus?: any;
|
|
749
|
+
latestVisibleStatus: string;
|
|
750
|
+
waitedMs: number;
|
|
751
|
+
pending: CompletedDebouncePending;
|
|
752
|
+
emittedAfterFinalizationTimeout: boolean;
|
|
753
|
+
}): Record<string, unknown> {
|
|
754
|
+
let parsed: any = null;
|
|
755
|
+
let parseError: string | undefined;
|
|
756
|
+
try {
|
|
757
|
+
parsed = this.adapter.getScriptParsedStatus();
|
|
758
|
+
} catch (error: any) {
|
|
759
|
+
parseError = error?.message || String(error);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
const visibleMessages = (Array.isArray(parsed?.messages) ? parsed.messages : [])
|
|
763
|
+
.filter((message: any) => isUserFacingChatMessage(message as ChatMessage));
|
|
764
|
+
const lastVisible = visibleMessages[visibleMessages.length - 1] as ChatMessage | undefined;
|
|
765
|
+
const lastVisibleRole = typeof lastVisible?.role === 'string' ? lastVisible.role.trim().toLowerCase() : null;
|
|
766
|
+
const lastVisibleKind = typeof (lastVisible as any)?.kind === 'string' ? (lastVisible as any).kind : null;
|
|
767
|
+
const lastVisibleContentLength = lastVisible ? flattenContent(lastVisible.content).trim().length : 0;
|
|
768
|
+
|
|
769
|
+
return {
|
|
770
|
+
providerType: this.type,
|
|
771
|
+
sessionId: this.instanceId,
|
|
772
|
+
providerSessionId: this.providerSessionId || null,
|
|
773
|
+
workspace: this.workingDir,
|
|
774
|
+
blockReason: args.blockReason,
|
|
775
|
+
emittedAfterFinalizationTimeout: args.emittedAfterFinalizationTimeout,
|
|
776
|
+
waitedMs: args.waitedMs,
|
|
777
|
+
maxWaitMs: COMPLETED_FINALIZATION_MAX_WAIT_MS,
|
|
778
|
+
adapterStatus: typeof args.latestStatus?.status === 'string' ? args.latestStatus.status : null,
|
|
779
|
+
latestVisibleStatus: args.latestVisibleStatus,
|
|
780
|
+
parsedStatus: typeof parsed?.status === 'string' ? parsed.status : (parseError ? 'parse_error' : 'unknown'),
|
|
781
|
+
parseError: parseError || undefined,
|
|
782
|
+
finalAssistantPresent: this.completionHasFinalAssistantMessage(parsed?.messages),
|
|
783
|
+
visibleMessageCount: visibleMessages.length,
|
|
784
|
+
lastVisibleRole,
|
|
785
|
+
lastVisibleKind,
|
|
786
|
+
lastVisibleContentLength,
|
|
787
|
+
pendingStartedAt: this.generatingStartedAt || null,
|
|
788
|
+
pendingFirstObservedAt: args.pending.firstObservedAt,
|
|
789
|
+
pendingTimestamp: args.pending.timestamp,
|
|
790
|
+
pendingDurationSec: args.pending.duration,
|
|
791
|
+
previousBlockReason: args.pending.loggedBlockReason || null,
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
|
|
746
795
|
private hasAdapterPendingResponse(): boolean {
|
|
747
796
|
const adapterAny = this.adapter as any;
|
|
748
797
|
if (adapterAny?.isWaitingForResponse === true) return true;
|
|
@@ -828,7 +877,23 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
828
877
|
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
829
878
|
return;
|
|
830
879
|
}
|
|
831
|
-
|
|
880
|
+
const completionDiagnostic = this.buildCompletedFinalizationDiagnostic({
|
|
881
|
+
blockReason,
|
|
882
|
+
latestStatus,
|
|
883
|
+
latestVisibleStatus,
|
|
884
|
+
waitedMs,
|
|
885
|
+
pending,
|
|
886
|
+
emittedAfterFinalizationTimeout: true,
|
|
887
|
+
});
|
|
888
|
+
LOG.warn('CLI', `[${this.type}] emitting completed event after ${waitedMs}ms without finalized assistant turn (${blockReason})`);
|
|
889
|
+
this.pushEvent({
|
|
890
|
+
event: 'agent:generating_completed',
|
|
891
|
+
chatTitle: pending.chatTitle,
|
|
892
|
+
duration: pending.duration,
|
|
893
|
+
timestamp: pending.timestamp,
|
|
894
|
+
finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
895
|
+
completionDiagnostic,
|
|
896
|
+
});
|
|
832
897
|
this.completedDebouncePending = null;
|
|
833
898
|
this.completedDebounceTimer = null;
|
|
834
899
|
this.generatingStartedAt = 0;
|