@adhdev/daemon-core 0.8.94 → 0.8.95
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 +182 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +182 -30
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +3 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/providers/cli-provider-instance.ts +66 -31
package/dist/index.js
CHANGED
|
@@ -7673,6 +7673,125 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
7673
7673
|
return { sessions: [], hasMore: false };
|
|
7674
7674
|
}
|
|
7675
7675
|
}
|
|
7676
|
+
function normalizeCanonicalHermesMessageContent(content) {
|
|
7677
|
+
if (typeof content === "string") return content.trim();
|
|
7678
|
+
if (content == null) return "";
|
|
7679
|
+
try {
|
|
7680
|
+
return JSON.stringify(content).trim();
|
|
7681
|
+
} catch {
|
|
7682
|
+
return String(content).trim();
|
|
7683
|
+
}
|
|
7684
|
+
}
|
|
7685
|
+
function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
|
|
7686
|
+
const numericTimestamp = Number(message.receivedAt || message.timestamp || message.ts || 0);
|
|
7687
|
+
if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
|
|
7688
|
+
const stringTimestamp = typeof message.ts === "string" ? Date.parse(message.ts) : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
|
|
7689
|
+
if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
|
|
7690
|
+
return fallbackTs;
|
|
7691
|
+
}
|
|
7692
|
+
function readExistingHermesSessionStartRecord(historySessionId) {
|
|
7693
|
+
try {
|
|
7694
|
+
const dir = path7.join(HISTORY_DIR, "hermes-cli");
|
|
7695
|
+
if (!fs3.existsSync(dir)) return null;
|
|
7696
|
+
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
7697
|
+
for (const file of files) {
|
|
7698
|
+
const lines = fs3.readFileSync(path7.join(dir, file), "utf-8").split("\n").filter(Boolean);
|
|
7699
|
+
for (const line of lines) {
|
|
7700
|
+
try {
|
|
7701
|
+
const parsed = JSON.parse(line);
|
|
7702
|
+
if (parsed.historySessionId !== historySessionId) continue;
|
|
7703
|
+
if (parsed.kind === "session_start" && parsed.role === "system") {
|
|
7704
|
+
return parsed;
|
|
7705
|
+
}
|
|
7706
|
+
} catch {
|
|
7707
|
+
}
|
|
7708
|
+
}
|
|
7709
|
+
}
|
|
7710
|
+
return null;
|
|
7711
|
+
} catch {
|
|
7712
|
+
return null;
|
|
7713
|
+
}
|
|
7714
|
+
}
|
|
7715
|
+
function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
|
|
7716
|
+
const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
|
|
7717
|
+
if (!normalizedSessionId) return false;
|
|
7718
|
+
try {
|
|
7719
|
+
const sessionFilePath = path7.join(os5.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
|
|
7720
|
+
if (!fs3.existsSync(sessionFilePath)) return false;
|
|
7721
|
+
const raw = JSON.parse(fs3.readFileSync(sessionFilePath, "utf-8"));
|
|
7722
|
+
const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
|
|
7723
|
+
const dir = path7.join(HISTORY_DIR, "hermes-cli");
|
|
7724
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
7725
|
+
const existingSessionStart = readExistingHermesSessionStartRecord(normalizedSessionId);
|
|
7726
|
+
const records = [];
|
|
7727
|
+
if (existingSessionStart) {
|
|
7728
|
+
records.push({
|
|
7729
|
+
...existingSessionStart,
|
|
7730
|
+
historySessionId: normalizedSessionId
|
|
7731
|
+
});
|
|
7732
|
+
}
|
|
7733
|
+
let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
|
|
7734
|
+
for (const message of canonicalMessages) {
|
|
7735
|
+
const role = String(message.role || "").trim();
|
|
7736
|
+
const content = normalizeCanonicalHermesMessageContent(message.content);
|
|
7737
|
+
if (!content) continue;
|
|
7738
|
+
const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
|
|
7739
|
+
fallbackTs = receivedAt + 1;
|
|
7740
|
+
if (role === "user") {
|
|
7741
|
+
records.push({
|
|
7742
|
+
ts: new Date(receivedAt).toISOString(),
|
|
7743
|
+
receivedAt,
|
|
7744
|
+
role: "user",
|
|
7745
|
+
content,
|
|
7746
|
+
kind: "standard",
|
|
7747
|
+
agent: "hermes-cli",
|
|
7748
|
+
historySessionId: normalizedSessionId
|
|
7749
|
+
});
|
|
7750
|
+
continue;
|
|
7751
|
+
}
|
|
7752
|
+
if (role === "assistant") {
|
|
7753
|
+
records.push({
|
|
7754
|
+
ts: new Date(receivedAt).toISOString(),
|
|
7755
|
+
receivedAt,
|
|
7756
|
+
role: "assistant",
|
|
7757
|
+
content,
|
|
7758
|
+
kind: "standard",
|
|
7759
|
+
agent: "hermes-cli",
|
|
7760
|
+
historySessionId: normalizedSessionId
|
|
7761
|
+
});
|
|
7762
|
+
continue;
|
|
7763
|
+
}
|
|
7764
|
+
if (role === "tool") {
|
|
7765
|
+
records.push({
|
|
7766
|
+
ts: new Date(receivedAt).toISOString(),
|
|
7767
|
+
receivedAt,
|
|
7768
|
+
role: "assistant",
|
|
7769
|
+
content,
|
|
7770
|
+
kind: "tool",
|
|
7771
|
+
senderName: "Tool",
|
|
7772
|
+
agent: "hermes-cli",
|
|
7773
|
+
historySessionId: normalizedSessionId
|
|
7774
|
+
});
|
|
7775
|
+
}
|
|
7776
|
+
}
|
|
7777
|
+
if (records.length === 0) return false;
|
|
7778
|
+
const prefix = `${normalizedSessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
7779
|
+
for (const file of fs3.readdirSync(dir)) {
|
|
7780
|
+
if (file.startsWith(prefix) && file.endsWith(".jsonl")) {
|
|
7781
|
+
fs3.unlinkSync(path7.join(dir, file));
|
|
7782
|
+
}
|
|
7783
|
+
}
|
|
7784
|
+
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
7785
|
+
const filePath = path7.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
7786
|
+
fs3.writeFileSync(filePath, `${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
7787
|
+
`, "utf-8");
|
|
7788
|
+
invalidatePersistedSavedHistoryIndex("hermes-cli", dir);
|
|
7789
|
+
savedHistorySessionCache.delete("hermes-cli");
|
|
7790
|
+
return true;
|
|
7791
|
+
} catch {
|
|
7792
|
+
return false;
|
|
7793
|
+
}
|
|
7794
|
+
}
|
|
7676
7795
|
|
|
7677
7796
|
// src/providers/provider-patch-state.ts
|
|
7678
7797
|
function isControlValue(value) {
|
|
@@ -12583,6 +12702,7 @@ var CliProviderInstance = class {
|
|
|
12583
12702
|
historyWriter;
|
|
12584
12703
|
runtimeMessages = [];
|
|
12585
12704
|
lastPersistedHistoryMessages = [];
|
|
12705
|
+
lastCanonicalHermesSyncMtimeMs = 0;
|
|
12586
12706
|
instanceId;
|
|
12587
12707
|
suppressIdleHistoryReplay = false;
|
|
12588
12708
|
errorMessage = void 0;
|
|
@@ -12615,34 +12735,7 @@ var CliProviderInstance = class {
|
|
|
12615
12735
|
await this.enforceFreshSessionLaunchIfNeeded();
|
|
12616
12736
|
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
12617
12737
|
if (this.providerSessionId) {
|
|
12618
|
-
this.
|
|
12619
|
-
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
12620
|
-
this.historyWriter.seedSessionHistory(
|
|
12621
|
-
this.type,
|
|
12622
|
-
restoredHistory.messages,
|
|
12623
|
-
this.providerSessionId,
|
|
12624
|
-
this.instanceId
|
|
12625
|
-
);
|
|
12626
|
-
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
12627
|
-
role: message.role,
|
|
12628
|
-
content: message.content,
|
|
12629
|
-
kind: message.kind,
|
|
12630
|
-
senderName: message.senderName,
|
|
12631
|
-
receivedAt: message.receivedAt
|
|
12632
|
-
}));
|
|
12633
|
-
this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
|
|
12634
|
-
if (restoredHistory.messages.length > 0) {
|
|
12635
|
-
this.adapter.seedCommittedMessages(
|
|
12636
|
-
restoredHistory.messages.map((message) => ({
|
|
12637
|
-
role: message.role,
|
|
12638
|
-
content: message.content,
|
|
12639
|
-
timestamp: message.receivedAt,
|
|
12640
|
-
receivedAt: message.receivedAt,
|
|
12641
|
-
kind: message.kind,
|
|
12642
|
-
senderName: message.senderName
|
|
12643
|
-
}))
|
|
12644
|
-
);
|
|
12645
|
-
}
|
|
12738
|
+
this.restorePersistedHistoryFromCurrentSession();
|
|
12646
12739
|
}
|
|
12647
12740
|
if (this.providerSessionId && this.launchMode === "resume") {
|
|
12648
12741
|
const resumedAt = Date.now();
|
|
@@ -12751,6 +12844,7 @@ var CliProviderInstance = class {
|
|
|
12751
12844
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
12752
12845
|
}
|
|
12753
12846
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
12847
|
+
const canonicalHermesBackedHistory = this.syncCanonicalHermesSavedHistoryIfNeeded();
|
|
12754
12848
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
12755
12849
|
if (parsedMessages.length > 0) {
|
|
12756
12850
|
const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
|
|
@@ -12768,7 +12862,7 @@ var CliProviderInstance = class {
|
|
|
12768
12862
|
senderName: typeof message.senderName === "string" ? message.senderName : void 0,
|
|
12769
12863
|
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
12770
12864
|
}));
|
|
12771
|
-
if (!shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
|
|
12865
|
+
if (!canonicalHermesBackedHistory && !shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
|
|
12772
12866
|
const incrementalMessages = buildIncrementalHistoryAppendMessages(this.lastPersistedHistoryMessages, normalizedMessagesToSave);
|
|
12773
12867
|
this.historyWriter.appendNewMessages(
|
|
12774
12868
|
this.type,
|
|
@@ -12778,7 +12872,9 @@ var CliProviderInstance = class {
|
|
|
12778
12872
|
this.providerSessionId
|
|
12779
12873
|
);
|
|
12780
12874
|
}
|
|
12781
|
-
|
|
12875
|
+
if (!canonicalHermesBackedHistory) {
|
|
12876
|
+
this.lastPersistedHistoryMessages = normalizedMessagesToSave;
|
|
12877
|
+
}
|
|
12782
12878
|
}
|
|
12783
12879
|
this.applyProviderResponse(parsedStatus, { phase: "immediate" });
|
|
12784
12880
|
const surface = resolveProviderStateSurface({
|
|
@@ -13235,6 +13331,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
13235
13331
|
this.providerSessionId = nextSessionId;
|
|
13236
13332
|
this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
|
|
13237
13333
|
this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
|
|
13334
|
+
this.restorePersistedHistoryFromCurrentSession();
|
|
13238
13335
|
this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
|
|
13239
13336
|
this.onProviderSessionResolved?.({
|
|
13240
13337
|
instanceId: this.instanceId,
|
|
@@ -13246,6 +13343,61 @@ ${effect.notification.body || ""}`.trim();
|
|
|
13246
13343
|
});
|
|
13247
13344
|
LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
|
|
13248
13345
|
}
|
|
13346
|
+
syncCanonicalHermesSavedHistoryIfNeeded() {
|
|
13347
|
+
if (this.type !== "hermes-cli" || !this.providerSessionId) return false;
|
|
13348
|
+
try {
|
|
13349
|
+
const canonicalPath = path11.join(os11.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
|
|
13350
|
+
if (!fs5.existsSync(canonicalPath)) return false;
|
|
13351
|
+
const stat = fs5.statSync(canonicalPath);
|
|
13352
|
+
if (stat.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
|
|
13353
|
+
const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
|
|
13354
|
+
if (!rebuilt) return false;
|
|
13355
|
+
this.lastCanonicalHermesSyncMtimeMs = stat.mtimeMs;
|
|
13356
|
+
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
13357
|
+
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
13358
|
+
role: message.role,
|
|
13359
|
+
content: message.content,
|
|
13360
|
+
kind: message.kind,
|
|
13361
|
+
senderName: message.senderName,
|
|
13362
|
+
receivedAt: message.receivedAt
|
|
13363
|
+
}));
|
|
13364
|
+
return true;
|
|
13365
|
+
} catch {
|
|
13366
|
+
return false;
|
|
13367
|
+
}
|
|
13368
|
+
}
|
|
13369
|
+
restorePersistedHistoryFromCurrentSession() {
|
|
13370
|
+
if (!this.providerSessionId) return;
|
|
13371
|
+
this.syncCanonicalHermesSavedHistoryIfNeeded();
|
|
13372
|
+
this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
|
|
13373
|
+
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
13374
|
+
this.historyWriter.seedSessionHistory(
|
|
13375
|
+
this.type,
|
|
13376
|
+
restoredHistory.messages,
|
|
13377
|
+
this.providerSessionId,
|
|
13378
|
+
this.instanceId
|
|
13379
|
+
);
|
|
13380
|
+
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
13381
|
+
role: message.role,
|
|
13382
|
+
content: message.content,
|
|
13383
|
+
kind: message.kind,
|
|
13384
|
+
senderName: message.senderName,
|
|
13385
|
+
receivedAt: message.receivedAt
|
|
13386
|
+
}));
|
|
13387
|
+
this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
|
|
13388
|
+
if (restoredHistory.messages.length > 0) {
|
|
13389
|
+
this.adapter.seedCommittedMessages(
|
|
13390
|
+
restoredHistory.messages.map((message) => ({
|
|
13391
|
+
role: message.role,
|
|
13392
|
+
content: message.content,
|
|
13393
|
+
timestamp: message.receivedAt,
|
|
13394
|
+
receivedAt: message.receivedAt,
|
|
13395
|
+
kind: message.kind,
|
|
13396
|
+
senderName: message.senderName
|
|
13397
|
+
}))
|
|
13398
|
+
);
|
|
13399
|
+
}
|
|
13400
|
+
}
|
|
13249
13401
|
getProbeDirectories() {
|
|
13250
13402
|
const dirs = /* @__PURE__ */ new Set();
|
|
13251
13403
|
const addDir = (value) => {
|