Merge branch 'perf/local-dbupd' into perf/local-opt

This commit is contained in:
2026-10-16 10:20:59 +07:00
21 changed files with 1323 additions and 58 deletions
+4 -1
View File
@@ -1,6 +1,6 @@
/**
* @file Settings.tsx
* @description The install-wide settings, as three pages of the Settings nav (`SettingsHub.tsx`): `section="data"` — total cost, database overview, workspace housekeeping (dry run first, confirm before a real run), import, remote sources, push ingest (`components/settings/PushIngestSettings.tsx`), privacy (`components/settings/PrivacySettings.tsx`), the daily database backup (`components/settings/BackupSettings.tsx`), export, this browser's preferences backup, session cleanup (whole days ≥ 1, a dry-run count in its confirm) and the danger zone (typed confirmation) —, `section="about"` (the System page) — the start-at-login switch and Quit (`AutostartSettings`), then the server process (release, uptime, platform, CPU, memory, live connections), how AgentHub is installed (the update check's cached status) and the database file — and `section="notifications"` — browser notifications (per-browser, with a reset) and alerts (server-wide). Server info (`/api/settings/info`) is read only by Data and About, refreshed on activity at most every 10 s. Language, theme and the pet live on the Appearance page (`components/settings/AppearanceSettings.tsx`); per-tool settings live in that tool's page under `/settings/agents/<id>`.
* @description The install-wide settings, as three pages of the Settings nav (`SettingsHub.tsx`): `section="data"` — total cost, database overview, workspace housekeeping (dry run first, confirm before a real run), import, remote sources, push ingest (`components/settings/PushIngestSettings.tsx`), privacy (`components/settings/PrivacySettings.tsx`), the daily database backup (`components/settings/BackupSettings.tsx`), export, this browser's preferences backup, session cleanup (whole days ≥ 1, a dry-run count in its confirm; under it the opt-in automatic cleanup and Compact, `components/settings/RetentionSettings.tsx`) and the danger zone (typed confirmation) —, `section="about"` (the System page) — the start-at-login switch and Quit (`AutostartSettings`), then the server process (release, uptime, platform, CPU, memory, live connections), how AgentHub is installed (the update check's cached status) and the database file — and `section="notifications"` — browser notifications (per-browser, with a reset) and alerts (server-wide). Server info (`/api/settings/info`) is read only by Data and About, refreshed on activity at most every 10 s. Language, theme and the pet live on the Appearance page (`components/settings/AppearanceSettings.tsx`); per-tool settings live in that tool's page under `/settings/agents/<id>`.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
/* =============================================================================
@@ -103,6 +103,7 @@ import { RemoteSources } from "../components/RemoteSources";
import { PushIngestSettings } from "../components/settings/PushIngestSettings";
import { PrivacySettings } from "../components/settings/PrivacySettings";
import { BackupSettings } from "../components/settings/BackupSettings";
import { RetentionSettings } from "../components/settings/RetentionSettings";
import { AutostartSettings } from "../components/settings/AutostartSettings";
import { usePermissions } from "../components/AuthGate";
import { Skeleton } from "../components/Skeleton";
@@ -1054,6 +1055,8 @@ export function Settings({
</button>
{actionBanner(["cleanup"])}
<RetentionSettings />
</section>
{/* ─── THIS BROWSER'S PREFERENCES ─── */}
@@ -77,6 +77,18 @@ vi.mock("../../lib/api", async (importOriginal) => {
env_owned: { dir: false, hour: false, keep: false },
})),
},
retention: {
get: vi.fn(async () => ({
days: 0,
max_days: 3650,
env_owned: { days: false },
last_run: null,
space: null,
db_size: 0,
compacting: false,
last_compact: null,
})),
},
},
},
};
@@ -9357,6 +9357,108 @@ exit 0
</svg>
Run Cleanup
</button>
<div
class="border-t border-border pt-4 space-y-3"
>
<div>
<h4
class="text-xs font-medium text-fg-secondary"
>
Automatic cleanup
</h4>
<p
class="text-xs text-fg-muted"
>
Off by default. When on, the hourly maintenance deletes finished sessions (completed, error, abandoned) that started more than this many days ago — with their events, agents and token usage — a little at a time.
</p>
</div>
<div
class="flex flex-wrap items-end gap-3"
>
<div
class="bg-surface-2 rounded-lg px-4 py-3"
>
<label
class="text-xs text-fg-secondary block mb-2"
for="retention-days"
>
Delete sessions older than
</label>
<div
class="flex items-center gap-2"
>
<input
class="input w-20 text-sm text-right font-mono"
id="retention-days"
inputmode="numeric"
max="3650"
min="0"
step="1"
type="number"
value="0"
/>
<span
class="text-xs text-fg-muted"
>
days
</span>
</div>
</div>
<button
class="btn-primary px-4 py-2 text-sm disabled:opacity-50 disabled:cursor-not-allowed"
disabled=""
type="button"
>
Save
</button>
</div>
<p
class="text-xs text-fg-secondary"
>
Automatic cleanup is off.
</p>
<div
class="flex flex-wrap items-center gap-3"
>
<button
class="text-xs px-3 py-1.5 rounded-md transition-colors disabled:opacity-50 text-fg-secondary hover:text-fg-primary hover:bg-surface-4 border border-border"
type="button"
>
<svg
class="lucide lucide-minimize2 w-3 h-3 inline mr-1"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<polyline
points="4 14 10 14 10 20"
/>
<polyline
points="20 10 14 10 14 4"
/>
<line
x1="14"
x2="21"
y1="10"
y2="3"
/>
<line
x1="3"
x2="10"
y1="21"
y2="14"
/>
</svg>
Compact now
</button>
</div>
</div>
</section>
<section
class="scroll-mt-24"
@@ -362,6 +362,18 @@ vi.mock("../../lib/api", async (importOriginal) => {
env_owned: { dir: false, hour: false, keep: false },
}),
},
retention: {
get: r({
days: 0,
max_days: 3650,
env_owned: { days: false },
last_run: null,
space: null,
db_size: 0,
compacting: false,
last_compact: null,
}),
},
exportData: () => "/api/settings/export",
cleanup: r({
ok: true,