feat: OpenClaw session import with sorted history
Backend: - New OpenClawEndpoint with GET /api/openclaw/sessions and POST /api/openclaw/import - Lists all OpenClaw sessions with preview messages, model, summary - Imports user/assistant text messages (skips tool-use/tool-result) - Cleans user messages (removes webchat prefixes, cron tags, conversation info blocks) - Re-import support: deletes previous openclaw-import chains before importing - New DatabaseService methods: CreateChainForImport, CreateMessageForImport, DeleteOpenClawImport - Added SortKey to MessageRecord (computed: openclaw-import gets id-10B, else id) History sorting: - OpenClaw-imported messages always appear before native messages - Sort by CASE WHEN tag='openclaw-import' THEN id-10000000000 ELSE id END - Cursor-based paging updated from beforeId/afterId to beforeSortKey/afterSortKey - All history queries (GetLatestActive, Before, After, CountBefore) updated Frontend: - Dashboard: new 'OpenClaw Import' menu item in session card dropdown - Modal: shows OpenClaw sessions with metadata, summary, preview messages - Imported messages display blue 'OC' badge in chat - API functions: apiGetOpenclawSessions, apiImportOpenclawSession - History paging updated to use sortKey cursors
This commit is contained in:
1 parent
1597c10a3c
commit
3b7bdb7a20
10 files changed
+750
-38
No files matched your search
+28
-4
@@ -96,16 +96,16 @@ async function apiDeleteAgent(agentId) {
|
||||
return fetch(`/api/agents/${agentId}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
async function apiHistory(sessionId, beforeId, includeDeleted = false) {
|
||||
async function apiHistory(sessionId, beforeSortKey, includeDeleted = false) {
|
||||
let url = `/api/history?sessionId=${sessionId}`;
|
||||
if (beforeId) url += `&beforeId=${beforeId}`;
|
||||
if (beforeSortKey) url += `&beforeSortKey=${beforeSortKey}`;
|
||||
if (includeDeleted) url += `&includeDeleted=true`;
|
||||
const resp = await fetch(url);
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
async function apiHistoryPoll(sessionId, afterId, includeDeleted = false) {
|
||||
let url = `/api/history/poll?sessionId=${sessionId}&afterId=${afterId}`;
|
||||
async function apiHistoryPoll(sessionId, afterSortKey, includeDeleted = false) {
|
||||
let url = `/api/history/poll?sessionId=${sessionId}&afterSortKey=${afterSortKey}`;
|
||||
if (includeDeleted) url += `&includeDeleted=true`;
|
||||
const resp = await fetch(url);
|
||||
return resp.json();
|
||||
@@ -544,6 +544,30 @@ async function apiKreaGenerate(prompt, model, width, height) {
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
// ── OpenClaw Import API ──
|
||||
|
||||
async function apiGetOpenclawSessions() {
|
||||
const resp = await fetch('/api/openclaw/sessions');
|
||||
if (!resp.ok) {
|
||||
const err = await resp.json().catch(() => ({}));
|
||||
throw new Error(err.error || 'OpenClaw-Sessions konnten nicht geladen werden');
|
||||
}
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
async function apiImportOpenclawSession(openclawSessionId, sessionId) {
|
||||
const resp = await fetch('/api/openclaw/import', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ openclawSessionId, sessionId })
|
||||
});
|
||||
if (!resp.ok) {
|
||||
const err = await resp.json().catch(() => ({}));
|
||||
throw new Error(err.error || 'Import fehlgeschlagen');
|
||||
}
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
// ── Backup API ──
|
||||
|
||||
async function apiBackupDb() {
|
||||
|
||||
Reference in new issue
Block a user