larkin 0.4.24 → 0.4.26
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/agent/context-prompt.cjs +18 -0
- package/dist/agent/context-prompt.mjs +18 -0
- package/dist/app/agent-cli.mjs +1 -1
- package/dist/app/agent-config.mjs +9 -3
- package/dist/app/runtime-model-directory.mjs +22 -3
- package/dist/dashboard/dashboard-config-controller.mjs +24 -14
- package/dist/dashboard/dashboard-view-model.mjs +5 -1
- package/dist/dashboard/web/assets/dashboard.css +1 -1
- package/dist/dashboard/web/assets/dashboard.js +15 -15
- package/dist/feishu/host-shell.cjs +28 -8
- package/dist/feishu/host-shell.mjs +28 -8
- package/dist/runtime/pi-distribution-label.cjs +6 -0
- package/dist/runtime/pi-distribution-label.mjs +3 -0
- package/dist/runtime/pi-provider-config.cjs +20 -1
- package/dist/runtime/pi-provider-config.mjs +16 -0
- package/dist/runtime/runtime-adapters.mjs +20 -6
- package/dist/runtime/runtime-host.cjs +100 -48
- package/dist/runtime/runtime-host.mjs +100 -48
- package/package.json +1 -1
|
@@ -36,6 +36,63 @@ const BACKGROUND_COMPLETION_IMMEDIATE_RETRY_LIMIT = 5;
|
|
|
36
36
|
const DEFAULT_SUBAGENT_RECONCILE_INTERVAL_MS = 15_000;
|
|
37
37
|
const now = () => new Date().toISOString();
|
|
38
38
|
const isActiveDelivery = (status) => ["pending", "submitting", "accepted"].includes(status);
|
|
39
|
+
const previousSessionRefFor = (session, reason) => session.sessionId
|
|
40
|
+
? { sessionId: session.sessionId, file: session.sessionFile ?? null, closedAt: new Date().toISOString(), reason }
|
|
41
|
+
: null;
|
|
42
|
+
function parsePreviousSessionRef(value) {
|
|
43
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
44
|
+
return null;
|
|
45
|
+
const record = value;
|
|
46
|
+
if (typeof record.sessionId !== "string" || !record.sessionId)
|
|
47
|
+
return null;
|
|
48
|
+
if (typeof record.closedAt !== "string" || typeof record.reason !== "string")
|
|
49
|
+
return null;
|
|
50
|
+
return {
|
|
51
|
+
sessionId: record.sessionId,
|
|
52
|
+
file: typeof record.file === "string" && record.file ? record.file : null,
|
|
53
|
+
closedAt: record.closedAt,
|
|
54
|
+
reason: record.reason,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function loadPersistedPreviousSession(config, store) {
|
|
58
|
+
const fromConfig = parsePreviousSessionRef(config.previousSession);
|
|
59
|
+
if (fromConfig)
|
|
60
|
+
return fromConfig;
|
|
61
|
+
if (!store)
|
|
62
|
+
return null;
|
|
63
|
+
try {
|
|
64
|
+
const state = store.readJson("agentState", {});
|
|
65
|
+
return parsePreviousSessionRef(state.previousSessions?.[config.runtime]);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function persistPreviousSession(agent, previous) {
|
|
72
|
+
agent.previousSession = previous;
|
|
73
|
+
agent.config.previousSession = previous;
|
|
74
|
+
const store = agent.stateStore;
|
|
75
|
+
if (!store)
|
|
76
|
+
return;
|
|
77
|
+
try {
|
|
78
|
+
const current = store.readJson("agentState", { sessions: {} });
|
|
79
|
+
// Delivery-ledger mocks ignore the JSON key and would be clobbered by this write.
|
|
80
|
+
if (Array.isArray(current.records) && !("sessions" in current))
|
|
81
|
+
return;
|
|
82
|
+
const previousSessions = current.previousSessions && typeof current.previousSessions === "object"
|
|
83
|
+
&& !Array.isArray(current.previousSessions)
|
|
84
|
+
? { ...current.previousSessions }
|
|
85
|
+
: {};
|
|
86
|
+
if (previous)
|
|
87
|
+
previousSessions[agent.adapter.id] = previous;
|
|
88
|
+
else
|
|
89
|
+
delete previousSessions[agent.adapter.id];
|
|
90
|
+
store.writeJson("agentState", { ...current, previousSessions });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// In-memory ref still holds for this process; restart will miss it only if this write failed.
|
|
94
|
+
}
|
|
95
|
+
}
|
|
39
96
|
const REPLAY_FAILURE_CODES = new Set([
|
|
40
97
|
"canonical_inbox_row_missing", "canonical_inbox_malformed", "duplicate_message_id",
|
|
41
98
|
"inbox_state_conflict", "delivery_target_conflict", "structured_target_invalid",
|
|
@@ -457,17 +514,12 @@ export function createRuntimeHost(options) {
|
|
|
457
514
|
&& agent.piProactiveCompactionGeneration === agent.generation
|
|
458
515
|
&& agent.piProactiveCompactionSession === agent.session
|
|
459
516
|
? agent.piProactiveCompaction : null;
|
|
460
|
-
if (proactive
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
if (agent.adapter.id === "pi" && agent.piProactiveCompactionFailedGeneration === agent.generation) {
|
|
464
|
-
return { status: "deferred", deliveryId: record.deliveryId, reason: "Pi proactive compaction failed for the current session generation" };
|
|
465
|
-
}
|
|
517
|
+
if (proactive)
|
|
518
|
+
await proactive;
|
|
466
519
|
if (agent.adapter.id === "pi" && !busy && !agent.busy && !agent.turnInProgress && agent.session) {
|
|
467
520
|
const idleGate = proactivelyCompactPiAtIdle(agent, agent.session);
|
|
468
|
-
if (idleGate
|
|
469
|
-
|
|
470
|
-
}
|
|
521
|
+
if (idleGate)
|
|
522
|
+
await idleGate;
|
|
471
523
|
}
|
|
472
524
|
agent.submitting = true;
|
|
473
525
|
if (!busy)
|
|
@@ -541,20 +593,18 @@ export function createRuntimeHost(options) {
|
|
|
541
593
|
&& agent.piProactiveCompactionGeneration === agent.generation
|
|
542
594
|
&& agent.piProactiveCompactionSession === agent.session
|
|
543
595
|
? agent.piProactiveCompaction : null;
|
|
544
|
-
if (proactive
|
|
545
|
-
|
|
596
|
+
if (proactive)
|
|
597
|
+
await proactive;
|
|
546
598
|
if (agent.submitting || agent.starting) {
|
|
547
599
|
agent.retryAfterSubmit = true;
|
|
548
600
|
return;
|
|
549
601
|
}
|
|
550
|
-
if (agent.adapter.id === "pi" && agent.piProactiveCompactionFailedGeneration === agent.generation)
|
|
551
|
-
return;
|
|
552
602
|
if (agent.busy || agent.turnInProgress || !agent.session)
|
|
553
603
|
return;
|
|
554
604
|
if (agent.adapter.id === "pi") {
|
|
555
605
|
const idleGate = proactivelyCompactPiAtIdle(agent, agent.session);
|
|
556
|
-
if (idleGate
|
|
557
|
-
|
|
606
|
+
if (idleGate)
|
|
607
|
+
await idleGate;
|
|
558
608
|
}
|
|
559
609
|
const record = [...agent.records.values()].find((candidate) => candidate.status === "pending" || candidate.status === "submitting");
|
|
560
610
|
if (record)
|
|
@@ -760,14 +810,12 @@ export function createRuntimeHost(options) {
|
|
|
760
810
|
&& agent.piProactiveCompactionGeneration === agent.generation
|
|
761
811
|
&& agent.piProactiveCompactionSession === agent.session
|
|
762
812
|
? agent.piProactiveCompaction : null;
|
|
763
|
-
if (proactive
|
|
764
|
-
|
|
765
|
-
if (agent.adapter.id === "pi" && agent.piProactiveCompactionFailedGeneration === agent.generation)
|
|
766
|
-
return;
|
|
813
|
+
if (proactive)
|
|
814
|
+
await proactive;
|
|
767
815
|
if (agent.adapter.id === "pi" && !agent.busy && !agent.turnInProgress && agent.session) {
|
|
768
816
|
const idleGate = proactivelyCompactPiAtIdle(agent, agent.session);
|
|
769
|
-
if (idleGate
|
|
770
|
-
|
|
817
|
+
if (idleGate)
|
|
818
|
+
await idleGate;
|
|
771
819
|
}
|
|
772
820
|
if (agent.stopped || agent.busy || agent.turnInProgress || agent.submitting)
|
|
773
821
|
return;
|
|
@@ -949,8 +997,8 @@ export function createRuntimeHost(options) {
|
|
|
949
997
|
void ensureSession(agent).then(async () => {
|
|
950
998
|
const session = agent.session;
|
|
951
999
|
const proactive = session ? proactivelyCompactPiAtIdle(agent, session) : null;
|
|
952
|
-
if (proactive
|
|
953
|
-
|
|
1000
|
+
if (proactive)
|
|
1001
|
+
await proactive;
|
|
954
1002
|
reconcileSubagentLedger(agent, { forceMissing: true, missingReason: "pi session gone" });
|
|
955
1003
|
enqueueUndeliveredTerminalWakes(agent);
|
|
956
1004
|
await retryPending(agent);
|
|
@@ -1190,8 +1238,6 @@ export function createRuntimeHost(options) {
|
|
|
1190
1238
|
})();
|
|
1191
1239
|
const tracked = task.catch((error) => {
|
|
1192
1240
|
agent.piProactiveCompactionFailedGeneration = generation;
|
|
1193
|
-
emit({ type: "agent-status", agentId: agent.config.agentId, status: "error",
|
|
1194
|
-
error: "Pi proactive compaction failed; the current session generation is degraded" });
|
|
1195
1241
|
log("Pi proactive compaction failed", String(error));
|
|
1196
1242
|
return "failed";
|
|
1197
1243
|
}).finally(() => {
|
|
@@ -1325,10 +1371,7 @@ export function createRuntimeHost(options) {
|
|
|
1325
1371
|
emit({ type: "agent-status", agentId: agent.config.agentId, status: "active", readiness: agent.readiness });
|
|
1326
1372
|
}
|
|
1327
1373
|
const proactive = proactivelyCompactPiAtIdle(agent, session);
|
|
1328
|
-
void (proactive ?? Promise.resolve("noop")).then((
|
|
1329
|
-
if (outcome !== "failed")
|
|
1330
|
-
return retryPending(agent);
|
|
1331
|
-
});
|
|
1374
|
+
void (proactive ?? Promise.resolve("noop")).then(() => retryPending(agent));
|
|
1332
1375
|
queueMicrotask(() => { void scanAndPromoteAcceptedInboxUpdates(agent); });
|
|
1333
1376
|
}
|
|
1334
1377
|
else if (event.type === "runtime-observation") {
|
|
@@ -1457,7 +1500,7 @@ export function createRuntimeHost(options) {
|
|
|
1457
1500
|
const standingPrompt = options.promptBuilder.build({
|
|
1458
1501
|
agentId: agent.config.agentId, name: agent.config.displayName || agent.config.name,
|
|
1459
1502
|
description: agent.config.description || "", runtime: agent.adapter.id,
|
|
1460
|
-
cli: agentCliPromptCapabilities("larkin"),
|
|
1503
|
+
cli: agentCliPromptCapabilities("larkin"), previousSession: agent.previousSession,
|
|
1461
1504
|
});
|
|
1462
1505
|
const generation = ++agent.generation;
|
|
1463
1506
|
let completedSession = null;
|
|
@@ -1517,9 +1560,11 @@ export function createRuntimeHost(options) {
|
|
|
1517
1560
|
workspaceDir: agent.config.workspaceDir, stateDir: agent.config.stateDir, env: probeEnv }) : { runtime: "pi", state: "ready" };
|
|
1518
1561
|
if (readiness.state !== "ready")
|
|
1519
1562
|
throw new RuntimeSessionRecoveryError("recovery_staged_not_committed", "Pi context fallback readiness failed");
|
|
1563
|
+
const previousRef = previousSessionRefFor(oldSession, "context-window overflow");
|
|
1520
1564
|
const standingPrompt = options.promptBuilder.build({
|
|
1521
1565
|
agentId: agent.config.agentId, name: agent.config.displayName || agent.config.name,
|
|
1522
1566
|
description: agent.config.description || "", runtime: agent.adapter.id, cli: agentCliPromptCapabilities("larkin"),
|
|
1567
|
+
previousSession: previousRef,
|
|
1523
1568
|
});
|
|
1524
1569
|
let fresh;
|
|
1525
1570
|
try {
|
|
@@ -1548,6 +1593,7 @@ export function createRuntimeHost(options) {
|
|
|
1548
1593
|
const oldConfigSessionId = agent.config.sessionId;
|
|
1549
1594
|
const oldReadiness = agent.readiness;
|
|
1550
1595
|
const oldDisabledReason = agent.disabledReason;
|
|
1596
|
+
const oldPreviousSession = agent.previousSession;
|
|
1551
1597
|
const oldRecord = { ...record, input: { ...record.input } };
|
|
1552
1598
|
let durableRollback = null;
|
|
1553
1599
|
let rearmedCount = 1;
|
|
@@ -1563,6 +1609,7 @@ export function createRuntimeHost(options) {
|
|
|
1563
1609
|
agent.launchId = crypto.randomUUID();
|
|
1564
1610
|
agent.config.sessionId = null;
|
|
1565
1611
|
agent.session = fresh;
|
|
1612
|
+
persistPreviousSession(agent, previousRef);
|
|
1566
1613
|
agent.readiness = readiness;
|
|
1567
1614
|
agent.disabledReason = null;
|
|
1568
1615
|
for (const candidate of agent.records.values()) {
|
|
@@ -1597,6 +1644,7 @@ export function createRuntimeHost(options) {
|
|
|
1597
1644
|
agent.launchId = oldLaunchId;
|
|
1598
1645
|
agent.config.sessionId = oldConfigSessionId;
|
|
1599
1646
|
agent.session = oldSession;
|
|
1647
|
+
persistPreviousSession(agent, oldPreviousSession);
|
|
1600
1648
|
agent.readiness = oldReadiness;
|
|
1601
1649
|
agent.disabledReason = oldDisabledReason;
|
|
1602
1650
|
Object.assign(record, oldRecord);
|
|
@@ -1611,17 +1659,15 @@ export function createRuntimeHost(options) {
|
|
|
1611
1659
|
agent.config.sessionId = fresh.sessionId;
|
|
1612
1660
|
emit({ type: "session", agentId, runtime: agent.adapter.id, sessionId: fresh.sessionId, launchId: agent.launchId,
|
|
1613
1661
|
...(fresh.effectiveModel ? { model: fresh.effectiveModel } : {}),
|
|
1614
|
-
...(fresh.effectiveReasoningEffort ? { reasoningEffort: fresh.effectiveReasoningEffort } : {})
|
|
1662
|
+
...(fresh.effectiveReasoningEffort ? { reasoningEffort: fresh.effectiveReasoningEffort } : {}),
|
|
1663
|
+
...(agent.previousSession ? { previousSession: agent.previousSession } : {}) });
|
|
1615
1664
|
}
|
|
1616
1665
|
emit({ type: "agent-status", agentId, status: "active", readiness });
|
|
1617
1666
|
agent.piSessionOwner = probeEnv[PI_SUBAGENT_SESSION_OWNER_ENV];
|
|
1618
1667
|
await oldSession.close("Pi context fallback committed").catch((error) => log("previous Pi session close after fallback failed", String(error)));
|
|
1619
1668
|
reconcileAfterSessionSwap(agent);
|
|
1620
1669
|
const proactive = proactivelyCompactPiAtIdle(agent, fresh);
|
|
1621
|
-
void (proactive ?? Promise.resolve("noop")).then((
|
|
1622
|
-
if (outcome !== "failed")
|
|
1623
|
-
return retryPending(agent);
|
|
1624
|
-
});
|
|
1670
|
+
void (proactive ?? Promise.resolve("noop")).then(() => retryPending(agent));
|
|
1625
1671
|
return { generationChanged: true, sessionChanged: oldSessionId !== fresh.sessionId, turns: 0,
|
|
1626
1672
|
runtimeReady: true, pendingCount: remainingPendingCount, rearmedCount,
|
|
1627
1673
|
replayStatus: remainingPendingCount > 0 ? "pending" : "consumed", sessionId: fresh.sessionId };
|
|
@@ -1655,7 +1701,7 @@ export function createRuntimeHost(options) {
|
|
|
1655
1701
|
const standingPrompt = options.promptBuilder.build({
|
|
1656
1702
|
agentId: config.agentId, name: config.displayName || config.name,
|
|
1657
1703
|
description: config.description || "", runtime: adapter.id,
|
|
1658
|
-
cli: agentCliPromptCapabilities("larkin"),
|
|
1704
|
+
cli: agentCliPromptCapabilities("larkin"), previousSession: previous.previousSession,
|
|
1659
1705
|
});
|
|
1660
1706
|
const session = await adapter.createSession({
|
|
1661
1707
|
agentId: config.agentId, model: config.model, reasoningEffort: config.effort || null,
|
|
@@ -1761,10 +1807,11 @@ export function createRuntimeHost(options) {
|
|
|
1761
1807
|
: { runtime: agent.adapter.id, state: "ready" };
|
|
1762
1808
|
if (readiness.state !== "ready")
|
|
1763
1809
|
throw new RuntimePrerequisiteError(readiness);
|
|
1810
|
+
const previousRef = previousSessionRefFor(oldSession, "operator reset");
|
|
1764
1811
|
const standingPrompt = options.promptBuilder.build({
|
|
1765
1812
|
agentId: agent.config.agentId, name: agent.config.displayName || agent.config.name,
|
|
1766
1813
|
description: agent.config.description || "", runtime: agent.adapter.id,
|
|
1767
|
-
cli: agentCliPromptCapabilities("larkin"),
|
|
1814
|
+
cli: agentCliPromptCapabilities("larkin"), previousSession: previousRef,
|
|
1768
1815
|
});
|
|
1769
1816
|
const create = agent.adapter.createSession({
|
|
1770
1817
|
agentId: agent.config.agentId, model: agent.config.model, reasoningEffort: agent.config.effort || null,
|
|
@@ -1793,6 +1840,7 @@ export function createRuntimeHost(options) {
|
|
|
1793
1840
|
agent.launchId = crypto.randomUUID();
|
|
1794
1841
|
agent.config.sessionId = null;
|
|
1795
1842
|
agent.session = fresh;
|
|
1843
|
+
persistPreviousSession(agent, previousRef);
|
|
1796
1844
|
agent.readiness = readiness;
|
|
1797
1845
|
agent.disabledReason = null;
|
|
1798
1846
|
};
|
|
@@ -1811,7 +1859,8 @@ export function createRuntimeHost(options) {
|
|
|
1811
1859
|
agent.config.sessionId = fresh.sessionId;
|
|
1812
1860
|
emit({ type: "session", agentId, runtime: agent.adapter.id, sessionId: fresh.sessionId, launchId: agent.launchId,
|
|
1813
1861
|
...(fresh.effectiveModel ? { model: fresh.effectiveModel } : {}),
|
|
1814
|
-
...(fresh.effectiveReasoningEffort ? { reasoningEffort: fresh.effectiveReasoningEffort } : {})
|
|
1862
|
+
...(fresh.effectiveReasoningEffort ? { reasoningEffort: fresh.effectiveReasoningEffort } : {}),
|
|
1863
|
+
...(agent.previousSession ? { previousSession: agent.previousSession } : {}) });
|
|
1815
1864
|
}
|
|
1816
1865
|
emit({ type: "agent-status", agentId, status: "active", readiness });
|
|
1817
1866
|
agent.piSessionOwner = probeEnv[PI_SUBAGENT_SESSION_OWNER_ENV];
|
|
@@ -1871,10 +1920,12 @@ export function createRuntimeHost(options) {
|
|
|
1871
1920
|
}
|
|
1872
1921
|
if (readiness.state !== "ready")
|
|
1873
1922
|
throw new RuntimePrerequisiteError(readiness);
|
|
1923
|
+
const previousRef = previousSessionRefFor(oldSession, "context-window recovery");
|
|
1924
|
+
const oldPreviousSession = agent.previousSession;
|
|
1874
1925
|
const standingPrompt = options.promptBuilder.build({
|
|
1875
1926
|
agentId: agent.config.agentId, name: agent.config.displayName || agent.config.name,
|
|
1876
1927
|
description: agent.config.description || "", runtime: agent.adapter.id,
|
|
1877
|
-
cli: agentCliPromptCapabilities("larkin"),
|
|
1928
|
+
cli: agentCliPromptCapabilities("larkin"), previousSession: previousRef,
|
|
1878
1929
|
});
|
|
1879
1930
|
let fresh;
|
|
1880
1931
|
try {
|
|
@@ -1915,6 +1966,7 @@ export function createRuntimeHost(options) {
|
|
|
1915
1966
|
agent.generation = oldGeneration;
|
|
1916
1967
|
agent.launchId = oldLaunchId;
|
|
1917
1968
|
agent.config.sessionId = oldConfigSessionId;
|
|
1969
|
+
persistPreviousSession(agent, oldPreviousSession);
|
|
1918
1970
|
agent.readiness = oldReadiness;
|
|
1919
1971
|
agent.disabledReason = oldDisabledReason;
|
|
1920
1972
|
agent.records = new Map(oldRecords);
|
|
@@ -1947,6 +1999,7 @@ export function createRuntimeHost(options) {
|
|
|
1947
1999
|
agent.launchId = crypto.randomUUID();
|
|
1948
2000
|
agent.config.sessionId = null;
|
|
1949
2001
|
agent.session = fresh;
|
|
2002
|
+
persistPreviousSession(agent, previousRef);
|
|
1950
2003
|
agent.readiness = readiness;
|
|
1951
2004
|
agent.disabledReason = null;
|
|
1952
2005
|
for (const record of agent.records.values()) {
|
|
@@ -1962,7 +2015,8 @@ export function createRuntimeHost(options) {
|
|
|
1962
2015
|
agent.config.sessionId = fresh.sessionId;
|
|
1963
2016
|
emit({ type: "session", agentId, runtime: agent.adapter.id, sessionId: fresh.sessionId, launchId: agent.launchId,
|
|
1964
2017
|
...(fresh.effectiveModel ? { model: fresh.effectiveModel } : {}),
|
|
1965
|
-
...(fresh.effectiveReasoningEffort ? { reasoningEffort: fresh.effectiveReasoningEffort } : {})
|
|
2018
|
+
...(fresh.effectiveReasoningEffort ? { reasoningEffort: fresh.effectiveReasoningEffort } : {}),
|
|
2019
|
+
...(agent.previousSession ? { previousSession: agent.previousSession } : {}) });
|
|
1966
2020
|
}
|
|
1967
2021
|
emit({ type: "agent-status", agentId, status: "active", readiness });
|
|
1968
2022
|
durableRollback = null;
|
|
@@ -1971,10 +2025,7 @@ export function createRuntimeHost(options) {
|
|
|
1971
2025
|
.catch((error) => log("previous runtime close after context-window recovery failed", String(error)));
|
|
1972
2026
|
reconcileAfterSessionSwap(agent);
|
|
1973
2027
|
const proactive = proactivelyCompactPiAtIdle(agent, fresh);
|
|
1974
|
-
void (proactive ?? Promise.resolve("noop")).then((
|
|
1975
|
-
if (outcome !== "failed")
|
|
1976
|
-
return retryPending(agent);
|
|
1977
|
-
});
|
|
2028
|
+
void (proactive ?? Promise.resolve("noop")).then(() => retryPending(agent));
|
|
1978
2029
|
return { generationChanged: true, sessionChanged: oldSessionId !== fresh.sessionId, turns: 0,
|
|
1979
2030
|
runtimeReady: true, pendingCount: rearmed.remainingPendingCount, rearmedCount: rearmed.rearmedCount,
|
|
1980
2031
|
replayStatus: rearmed.remainingPendingCount > 0 ? "pending" : "consumed", sessionId: fresh.sessionId };
|
|
@@ -2054,7 +2105,8 @@ export function createRuntimeHost(options) {
|
|
|
2054
2105
|
}) : undefined,
|
|
2055
2106
|
compactionMachines: new Map(), compactionRecoveryInFlight: new Set(), piOverflowCompactionFailed: new Set(),
|
|
2056
2107
|
piProactiveCompaction: null, piProactiveCompactionGeneration: null, piProactiveCompactionSession: null,
|
|
2057
|
-
piProactiveCompactionFailedGeneration: null,
|
|
2108
|
+
piProactiveCompactionFailedGeneration: null,
|
|
2109
|
+
previousSession: loadPersistedPreviousSession(config, stateStore), readiness: null,
|
|
2058
2110
|
turnInProgress: false, turnHadFailure: false, turnHadAuthenticatedOutput: false, authFailureActive: false,
|
|
2059
2111
|
promotedInboxUpdateIds: new Set(),
|
|
2060
2112
|
backgroundCompletionQueue: [], backgroundCompletionKeys: new Set(),
|
|
@@ -2096,10 +2148,10 @@ export function createRuntimeHost(options) {
|
|
|
2096
2148
|
await recoverStalePiCompaction(agent);
|
|
2097
2149
|
const startupSession = agent.session;
|
|
2098
2150
|
const proactive = startupSession ? proactivelyCompactPiAtIdle(agent, startupSession) : null;
|
|
2099
|
-
|
|
2151
|
+
if (proactive)
|
|
2152
|
+
await proactive;
|
|
2100
2153
|
activeCount += 1;
|
|
2101
|
-
|
|
2102
|
-
await retryPending(agent);
|
|
2154
|
+
await retryPending(agent);
|
|
2103
2155
|
}
|
|
2104
2156
|
catch (error) {
|
|
2105
2157
|
const reason = error instanceof Error ? error.message : String(error);
|