@adhdev/daemon-core 0.9.82-rc.110 → 0.9.82-rc.112

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.mjs CHANGED
@@ -4646,6 +4646,8 @@ var init_provider_cli_adapter = __esm({
4646
4646
  pendingOutboundQueue = [];
4647
4647
  pendingOutboundFlushTimer = null;
4648
4648
  pendingOutboundFlushInFlight = false;
4649
+ providerErrorRetryTimer = null;
4650
+ providerErrorRetryKey = "";
4649
4651
  // Resize redraw suppression
4650
4652
  resizeSuppressUntil = 0;
4651
4653
  // Debug: status transition history
@@ -5252,6 +5254,11 @@ ${lastSnapshot}`;
5252
5254
  clearTimeout(this.ptyOutputFlushTimer);
5253
5255
  this.ptyOutputFlushTimer = null;
5254
5256
  }
5257
+ if (this.providerErrorRetryTimer) {
5258
+ clearTimeout(this.providerErrorRetryTimer);
5259
+ this.providerErrorRetryTimer = null;
5260
+ }
5261
+ this.providerErrorRetryKey = "";
5255
5262
  }
5256
5263
  clearStaleIdleResponseGuard(reason) {
5257
5264
  const blockingModal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
@@ -5401,6 +5408,7 @@ ${lastSnapshot}`;
5401
5408
  return;
5402
5409
  }
5403
5410
  if (status === "error") {
5411
+ if (this.maybeScheduleProviderErrorRetry(ctx, session)) return;
5404
5412
  this.applyError(ctx, session);
5405
5413
  return;
5406
5414
  }
@@ -5587,6 +5595,63 @@ ${lastSnapshot}`;
5587
5595
  });
5588
5596
  this.onStatusChange?.();
5589
5597
  }
5598
+ maybeScheduleProviderErrorRetry(ctx, session) {
5599
+ const retryPrompt = typeof session.retryPrompt === "string" ? String(session.retryPrompt).trim() : "";
5600
+ const retryDelayMs = typeof session.retryDelayMs === "number" ? Number(session.retryDelayMs) : NaN;
5601
+ if (!retryPrompt || !Number.isFinite(retryDelayMs) || retryDelayMs < 0) return false;
5602
+ if (!this.ptyProcess) return false;
5603
+ const retryAttempt = typeof session.retryAttempt === "number" ? Number(session.retryAttempt) : 0;
5604
+ const retryMaxAttempts = typeof session.retryMaxAttempts === "number" ? Number(session.retryMaxAttempts) : 0;
5605
+ const errorReason = typeof session.errorReason === "string" && session.errorReason.trim() ? session.errorReason.trim() : "provider_error";
5606
+ const retryKey = `${errorReason}:${retryAttempt}:${retryPrompt}`;
5607
+ if (this.providerErrorRetryTimer && this.providerErrorRetryKey === retryKey) return true;
5608
+ if (this.providerErrorRetryTimer) clearTimeout(this.providerErrorRetryTimer);
5609
+ this.providerErrorRetryKey = retryKey;
5610
+ this.clearIdleFinishCandidate("provider_error_retry");
5611
+ if (this.idleTimeout) {
5612
+ clearTimeout(this.idleTimeout);
5613
+ this.idleTimeout = null;
5614
+ }
5615
+ if (this.approvalExitTimeout) {
5616
+ clearTimeout(this.approvalExitTimeout);
5617
+ this.approvalExitTimeout = null;
5618
+ }
5619
+ this.providerErrorMessage = typeof session.errorMessage === "string" && session.errorMessage.trim() ? session.errorMessage.trim() : "Provider reported an error";
5620
+ this.providerErrorReason = errorReason;
5621
+ this.activeModal = null;
5622
+ this.responseSettleIgnoreUntil = Date.now() + retryDelayMs + this.timeouts.outputSettle + 400;
5623
+ this.setStatus("generating", "provider_error_retry_scheduled");
5624
+ this.recordTrace("provider_error_retry_scheduled", {
5625
+ retryPrompt,
5626
+ retryDelayMs,
5627
+ retryAttempt,
5628
+ retryMaxAttempts,
5629
+ errorReason,
5630
+ parsedStatus: ctx.parsedStatus || ctx.status
5631
+ });
5632
+ this.onStatusChange?.();
5633
+ this.providerErrorRetryTimer = setTimeout(() => {
5634
+ this.providerErrorRetryTimer = null;
5635
+ this.providerErrorRetryKey = "";
5636
+ if (!this.ptyProcess) return;
5637
+ this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
5638
+ this.submitRetryUsed = false;
5639
+ this.recordTrace("provider_error_retry_write", {
5640
+ retryPrompt,
5641
+ retryAttempt,
5642
+ retryMaxAttempts,
5643
+ errorReason
5644
+ });
5645
+ this.ptyProcess.write(`${retryPrompt}\r`);
5646
+ if (this.settleTimer) clearTimeout(this.settleTimer);
5647
+ this.settleTimer = setTimeout(() => {
5648
+ this.settleTimer = null;
5649
+ this.settledBuffer = this.recentOutputBuffer;
5650
+ this.evaluateSettled();
5651
+ }, this.timeouts.outputSettle + 150);
5652
+ }, retryDelayMs);
5653
+ return true;
5654
+ }
5590
5655
  applyIdle(ctx, now) {
5591
5656
  const { modal, lastParsedAssistant, prevStatus } = ctx;
5592
5657
  if (prevStatus === "waiting_approval") {
@@ -8475,11 +8540,17 @@ function buildSessionReadStateKey(sessionId, providerSessionId) {
8475
8540
  }
8476
8541
  function getSessionSeenAt(state, sessionId, providerSessionId) {
8477
8542
  const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
8478
- return state.sessionReads?.[providerKey] || state.sessionReads?.[sessionId] || 0;
8543
+ return Math.max(state.sessionReads?.[providerKey] || 0, state.sessionReads?.[sessionId] || 0);
8479
8544
  }
8480
8545
  function getSessionSeenMarker(state, sessionId, providerSessionId) {
8481
8546
  const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
8482
- return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
8547
+ const providerSeenAt = state.sessionReads?.[providerKey] || 0;
8548
+ const sessionSeenAt = state.sessionReads?.[sessionId] || 0;
8549
+ const providerMarker = state.sessionReadMarkers?.[providerKey] || "";
8550
+ const sessionMarker = state.sessionReadMarkers?.[sessionId] || "";
8551
+ if (sessionSeenAt > providerSeenAt && sessionMarker) return sessionMarker;
8552
+ if (providerSeenAt > sessionSeenAt && providerMarker) return providerMarker;
8553
+ return providerMarker || sessionMarker;
8483
8554
  }
8484
8555
  function getSessionNotificationDismissal(state, sessionId, providerSessionId) {
8485
8556
  const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
@@ -16871,7 +16942,20 @@ async function handleChatHistory(h, args) {
16871
16942
  if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
16872
16943
  }
16873
16944
  const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
16874
- const result = readProviderChatHistory(agentStr, {
16945
+ const exactNativeHistoryScope = Boolean(
16946
+ typeof args?.targetSessionId === "string" && args.targetSessionId.trim() || typeof args?.historySessionId === "string" && args.historySessionId.trim() || typeof args?.providerSessionId === "string" && args.providerSessionId.trim()
16947
+ );
16948
+ const result = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory) ? readCliProviderNativeHistory(agentStr, {
16949
+ canonicalHistory: provider?.canonicalHistory,
16950
+ historySessionId,
16951
+ workspace,
16952
+ offset: offset || 0,
16953
+ limit: limit || 30,
16954
+ excludeRecentCount,
16955
+ historyBehavior: provider?.historyBehavior,
16956
+ scripts: provider?.scripts,
16957
+ exactSessionScoped: exactNativeHistoryScope
16958
+ }) : readProviderChatHistory(agentStr, {
16875
16959
  canonicalHistory: provider?.canonicalHistory,
16876
16960
  historySessionId,
16877
16961
  workspace,
@@ -16881,6 +16965,26 @@ async function handleChatHistory(h, args) {
16881
16965
  historyBehavior: provider?.historyBehavior,
16882
16966
  scripts: provider?.scripts
16883
16967
  });
16968
+ if (supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory)) {
16969
+ const lookup = result.lookup === "workspace" ? "workspace" : "session";
16970
+ const messages = Array.isArray(result.messages) ? normalizeNativeHistoryMessages(agentStr, result.messages) : [];
16971
+ const historyProviderSessionId = typeof result?.providerSessionId === "string" ? result.providerSessionId : readHistorySessionIdFromMessages(messages) || historySessionId;
16972
+ const safeMapping = hasSafeNativeHistoryMapping({
16973
+ historySessionId: lookup === "workspace" ? void 0 : historySessionId,
16974
+ providerSessionId: lookup === "workspace" ? void 0 : historyProviderSessionId,
16975
+ workspace,
16976
+ nativeMessages: messages
16977
+ });
16978
+ if (result.source === "provider-native" && messages.length > 0 && !safeMapping) {
16979
+ return {
16980
+ success: true,
16981
+ messages: [],
16982
+ hasMore: false,
16983
+ source: "native-unavailable",
16984
+ agent: agentStr
16985
+ };
16986
+ }
16987
+ }
16884
16988
  return { success: true, ...result, agent: agentStr };
16885
16989
  } catch (e) {
16886
16990
  return { success: false, error: e.message };
@@ -19512,6 +19616,16 @@ function normalizeProviderSessionId(provider, providerSessionId) {
19512
19616
  }
19513
19617
 
19514
19618
  // src/providers/cli-provider-instance.ts
19619
+ function isIdleStatus(value) {
19620
+ const status = typeof value === "string" ? value.trim().toLowerCase() : "";
19621
+ return !status || status === "idle" || status === "ready";
19622
+ }
19623
+ function getMessageTime(message) {
19624
+ if (!message || typeof message !== "object") return 0;
19625
+ const record = message;
19626
+ const value = Number(record.receivedAt ?? record.timestamp ?? 0);
19627
+ return Number.isFinite(value) ? value : 0;
19628
+ }
19515
19629
  var COMPLETED_FINALIZATION_RETRY_MS = 1e3;
19516
19630
  var COMPLETED_FINALIZATION_MAX_WAIT_MS = 3e4;
19517
19631
  var IMAGE_MIME_EXTENSIONS = {
@@ -19773,7 +19887,7 @@ var CliProviderInstance = class {
19773
19887
  await this.adapter.spawn();
19774
19888
  await this.enforceFreshSessionLaunchIfNeeded();
19775
19889
  this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
19776
- if (this.providerSessionId) {
19890
+ if (this.providerSessionId && this.shouldHydrateExistingProviderHistory()) {
19777
19891
  this.restorePersistedHistoryFromCurrentSession();
19778
19892
  }
19779
19893
  if (this.providerSessionId && this.launchMode === "resume") {
@@ -19855,28 +19969,37 @@ var CliProviderInstance = class {
19855
19969
  this.provider,
19856
19970
  typeof adapterStatus?.providerSessionId === "string" ? adapterStatus.providerSessionId : ""
19857
19971
  );
19858
- if (adapterProviderSessionId) {
19859
- this.promoteProviderSessionId(adapterProviderSessionId);
19860
- }
19861
19972
  const autoApproveActive = this.maybeAutoApproveStatus(adapterStatus, Date.now());
19862
19973
  const visibleStatus = parseErrorMessage || parsedStatus?.status === "error" ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
19974
+ const runtime = this.adapter.getRuntimeMetadata();
19975
+ this.maybeAppendRuntimeRecoveryMessage(runtime);
19976
+ let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
19863
19977
  const parsedProviderSessionId = normalizeProviderSessionId(
19864
19978
  this.provider,
19865
19979
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
19866
19980
  );
19867
- if (parsedProviderSessionId) {
19981
+ const suppressFreshLaunchStartupReplay = this.shouldSuppressFreshLaunchStartupReplay(
19982
+ parsedMessages,
19983
+ parsedStatus,
19984
+ adapterStatus,
19985
+ parsedProviderSessionId
19986
+ );
19987
+ if (adapterProviderSessionId && !suppressFreshLaunchStartupReplay) {
19988
+ this.promoteProviderSessionId(adapterProviderSessionId);
19989
+ }
19990
+ if (parsedProviderSessionId && !suppressFreshLaunchStartupReplay) {
19868
19991
  this.promoteProviderSessionId(parsedProviderSessionId);
19869
19992
  }
19870
- const runtime = this.adapter.getRuntimeMetadata();
19871
- this.maybeAppendRuntimeRecoveryMessage(runtime);
19993
+ if (suppressFreshLaunchStartupReplay) {
19994
+ parsedMessages = [];
19995
+ }
19872
19996
  const activeChatId = this.providerSessionId || runtime?.runtimeId || this.instanceId;
19873
- let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
19874
19997
  const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
19875
19998
  if (historyMessageCount !== null) {
19876
19999
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
19877
20000
  }
19878
20001
  const mergedMessages = this.mergeConversationMessages(parsedMessages);
19879
- const canonicalBackedHistory = this.syncCanonicalSavedHistoryIfNeeded();
20002
+ const canonicalBackedHistory = this.shouldHydrateExistingProviderHistory() ? this.syncCanonicalSavedHistoryIfNeeded() : false;
19880
20003
  const statusMessages = canonicalBackedHistory && this.lastPersistedHistoryMessages.length > 0 ? this.lastPersistedHistoryMessages.map((message) => ({
19881
20004
  role: message.role,
19882
20005
  content: message.content,
@@ -19919,7 +20042,10 @@ var CliProviderInstance = class {
19919
20042
  this.lastPersistedHistoryMessages = normalizedMessagesToSave;
19920
20043
  }
19921
20044
  }
19922
- this.applyProviderResponse(parsedStatus, { phase: "immediate" });
20045
+ this.applyProviderResponse(
20046
+ suppressFreshLaunchStartupReplay && parsedStatus && typeof parsedStatus === "object" ? { ...parsedStatus, providerSessionId: void 0 } : parsedStatus,
20047
+ { phase: "immediate" }
20048
+ );
19923
20049
  const surface = resolveProviderStateSurface({
19924
20050
  summaryMetadata: this.summaryMetadata,
19925
20051
  controlValues: this.controlValues
@@ -20671,7 +20797,9 @@ ${effect.notification.body || ""}`.trim();
20671
20797
  this.providerSessionId = nextSessionId;
20672
20798
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
20673
20799
  this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
20674
- this.restorePersistedHistoryFromCurrentSession();
20800
+ if (this.shouldHydrateExistingProviderHistory()) {
20801
+ this.restorePersistedHistoryFromCurrentSession();
20802
+ }
20675
20803
  this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
20676
20804
  this.onProviderSessionResolved?.({
20677
20805
  instanceId: this.instanceId,
@@ -20683,6 +20811,18 @@ ${effect.notification.body || ""}`.trim();
20683
20811
  });
20684
20812
  LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
20685
20813
  }
20814
+ shouldHydrateExistingProviderHistory() {
20815
+ return this.launchMode === "resume" || this.launchMode === "manual";
20816
+ }
20817
+ shouldSuppressFreshLaunchStartupReplay(parsedMessages, parsedStatus, adapterStatus, parsedProviderSessionId = "") {
20818
+ if (this.launchMode !== "new") return false;
20819
+ if (this.providerSessionId) return false;
20820
+ if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return false;
20821
+ if (!isIdleStatus(adapterStatus?.status) || !isIdleStatus(parsedStatus?.status)) return false;
20822
+ if (parsedProviderSessionId) return true;
20823
+ const newestMessageAt = parsedMessages.reduce((newest, message) => Math.max(newest, getMessageTime(message)), 0);
20824
+ return newestMessageAt === 0;
20825
+ }
20686
20826
  syncCanonicalSavedHistoryIfNeeded() {
20687
20827
  if (!this.providerSessionId) return false;
20688
20828
  const canonicalHistory = this.provider.canonicalHistory;
@@ -31271,7 +31411,8 @@ function prepareSessionChatTailUpdate(input) {
31271
31411
  update: null
31272
31412
  };
31273
31413
  }
31274
- const fullMessages = normalizeChatMessages(Array.isArray(result.messages) ? result.messages : []);
31414
+ const rawMessages = Array.isArray(result.messages) ? result.messages : Array.isArray(result.messagesTail) ? result.messagesTail : [];
31415
+ const fullMessages = normalizeChatMessages(rawMessages);
31275
31416
  const messages = fullMessages;
31276
31417
  const title = typeof result.title === "string" ? result.title : void 0;
31277
31418
  const activeModal = normalizeChatTailActiveModal(result.activeModal);