kpt-labs-vault/00-Meta/Scripts/telegram-auto-save.ts
Floki 4135d1c2b9 🚀 Initial commit: KPT-LABS Obsidian Vault
- Wissensdatenbank Struktur
- Projekt-Übersichten
- Session-Management Templates
- Dashboard Integration
- README.md mit Recovery Guide
- System Snapshot Generator

Generiert: 2026-06-19
2026-06-20 22:44:04 +02:00

161 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Telegram Auto-Session-Save
*
* Diese Funktion wird vom Agenten (OWL) bei jedem Telegram-Turn aufgerufen.
* Sie zählt die Nachrichten und speichert bei Bedarf eine Zusammenfassung
* im Obsidian Vault.
*
* Zusätzlich wird eine Session-Zusammenfassung als Kontext für den nächsten
* Turn geladen, um Token zu sparen.
*/
import fs from 'fs';
import path from 'path';
const VAULT_PATH = 'E:\\OpenCode_Projekte\\obsidianVault';
const SESSIONS_DAILY = path.join(VAULT_PATH, '04-Sessions', 'Daily');
const TRACKER_PATH = path.join(VAULT_PATH, '04-Sessions', 'telegram-session-tracker.json');
interface SessionTracker {
session_id: string;
message_count: number;
last_save_at: string | null;
auto_save_interval: number;
model: string;
provider: string;
total_tokens_estimated: number;
created_at: string;
}
function loadTracker(): SessionTracker {
try {
if (fs.existsSync(TRACKER_PATH)) {
return JSON.parse(fs.readFileSync(TRACKER_PATH, 'utf-8'));
}
} catch { /* ignore */ }
return {
session_id: 'telegram-floki',
message_count: 0,
last_save_at: null,
auto_save_interval: 10,
model: 'openrouter/owl-alpha',
provider: 'openrouter',
total_tokens_estimated: 0,
created_at: new Date().toISOString(),
};
}
function saveTracker(tracker: SessionTracker): void {
fs.writeFileSync(TRACKER_PATH, JSON.stringify(tracker, null, 2), 'utf-8');
}
/**
* Prüft ob ein Auto-Save nötig ist und gibt ggf. die Zusammenfassung zurück
* die als Kontext für den nächsten Turn verwendet werden kann.
*/
export function checkAndSaveSession(userMessage: string, assistantReply: string): {
shouldSave: boolean;
summary?: string;
tokensSaved: number;
} {
const tracker = loadTracker();
tracker.message_count += 1; // 1 Turn = User + Assistant
// Tokens grob schätzen (4 chars pro Token)
const turnTokens = Math.ceil((userMessage.length + assistantReply.length) / 4);
tracker.total_tokens_estimated += turnTokens;
const shouldSave = tracker.message_count % tracker.auto_save_interval === 0;
if (shouldSave) {
// Zusammenfassung generieren
const now = new Date();
const dateStr = now.toISOString().split('T')[0];
const timeStr = now.toTimeString().split(' ')[0].substring(0, 5).replace(':', '-');
const summary = `Telegram-Session (${tracker.session_id}): ${tracker.message_count} Nachrichten, ~${tracker.total_tokens_estimated} Tokens. Letzte Nachricht: "${userMessage.substring(0, 60)}..."`;
const markdown = `---
session_id: ${tracker.session_id}
date: ${dateStr}
time: ${timeStr}
message_count: ${tracker.message_count}
model: ${tracker.model}
provider: ${tracker.provider}
tokens_estimated: ${tracker.total_tokens_estimated}
tags: [session, telegram, owl]
---
# 📱 Telegram Session: ${dateStr}
## 📊 Metriken
| Metrik | Wert |
|--------|------|
| **Nachrichten** | ${tracker.message_count} |
| **Geschätzte Tokens** | ~${tracker.total_tokens_estimated} |
| **Modell** | \`${tracker.model}\` |
| **Provider** | ${tracker.provider} |
## 📝 Zusammenfassung
${summary}
## 🏷️ Tags
\`#session\` \`#telegram\` \`#owl\`
---
*Auto-generiert vom OWL Agent Obsidian Sync*
`;
// Vault-Ordner sicherstellen
fs.mkdirSync(SESSIONS_DAILY, { recursive: true });
// Datei schreiben
const filename = `${dateStr}_${timeStr}_telegram.md`;
const filePath = path.join(SESSIONS_DAILY, filename);
fs.writeFileSync(filePath, markdown, 'utf-8');
// Tracker aktualisieren
tracker.last_save_at = now.toISOString();
saveTracker(tracker);
return {
shouldSave: true,
summary,
tokensSaved: turnTokens, // Diese Tokens werden "gespart" da Zusammenfassung kleiner ist
};
}
saveTracker(tracker);
return { shouldSave: false, tokensSaved: 0 };
}
/**
* Lädt die letzte Session-Zusammenfassung als Kontext
* um Token beim nächsten Request zu sparen
*/
export function loadLastSessionContext(): string | null {
try {
const files = fs.readdirSync(SESSIONS_DAILY)
.filter(f => f.endsWith('.md') && f.includes('telegram'))
.sort()
.reverse();
if (files.length === 0) return null;
const lastFile = path.join(SESSIONS_DAILY, files[0]);
const content = fs.readFileSync(lastFile, 'utf-8');
// Nur den Zusammenfassungs-Teil zurückgeben
const summaryMatch = content.match(/## 📝 Zusammenfassung\n\n([\s\S]*?)\n\n## /);
if (summaryMatch) {
return `Vorherige Session-Zusammenfassung:\n${summaryMatch[1]}\n\n~Tokens durch Kompression gespart.`;
}
return null;
} catch {
return null;
}
}