setup memory bank

This commit is contained in:
2025-08-18 08:52:15 +02:00
parent ee91c41a3d
commit 47b1223479
6 changed files with 753 additions and 4506 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
{
"nature": [
{
"subGenre": "Mountains",
"scene": "Snow peak sunrise",
"action": "Clouds drifting",
"camera": "Aerial drone orbit",
"accents": [
"mist layers",
"stars twinkle"
],
"mood": "majestic",
"lighting": "moonlit",
"style": "cinematic wide aspect"
},
{
"subGenre": "Mountains",
"scene": "Snow peak sunrise",
"action": "Hikers ascending",
"camera": "Tracking gimbal forward",
"accents": [
"snow glitter",
"aurora shimmer"
],
"mood": "adventurous",
"lighting": "starlight",
"style": "documentary realism"
},
{
"subGenre": "Mountains",
"scene": "Alpine meadow summer",
"action": "Wind blowing grass",
"camera": "Low tracking shot through flowers",
"accents": [
"butterflies flutter",
"fireflies sparkle"
],
"mood": "serene",
"lighting": "lantern glow",
"style": "dreamlike haze"
},
{
"subGenre": "Mountains",
"scene": "Alpine meadow summer",
"action": "Resting by rock",
"camera": "Medium telephoto close-up",
"accents": [
"sweat glistening",
"glowing embers"
],
"mood": "peaceful",
"lighting": "campfire light",
"style": "hyperreal HDR"
},
{
"subGenre": "Mountains",
"scene": "Ridge above clouds",
"action": "Clouds drifting",
"camera": "Tilted drone rise above ridge",
"accents": [
"sea of clouds",
"stars twinkle"
],
"mood": "ethereal",
"lighting": "aurora sky",
"style": "cinematic wide aspect"
},
{
"subGenre": "Mountains",
"scene": "Ridge above clouds",
"action": "Couple watching view",
"camera": "Over-shoulder dual frame",
"accents": [
"hand holding",
"lanterns glow"
],
"mood": "romantic",
"lighting": "moonlit",
"style": "soft film grain"
},
{
"subGenre": "Mountains",
"scene": "Glacial valley trail",
"action": "Walking slowly",
"camera": "Tracking dolly from behind",
"accents": [
"echoing footsteps",
"stars twinkle"
],
"mood": "mysterious",
"lighting": "starlight",
"style": "documentary realism"
},
{
"subGenre": "Mountains",
"scene": "Highland lake mirror",
"action": "Camping tents lit",
"camera": "Wide static shot",
"accents": [
"campfire smoke",
"fireflies sparkle"
],
"mood": "cozy",
"lighting": "lantern glow",
"style": "dreamlike haze"
},
{
"subGenre": "Mountains",
"scene": "Snowstorm ridge",
"action": "Tent flapping",
"camera": "Wide telephoto from distance",
"accents": [
"snowdrifts",
"aurora shimmer"
],
"mood": "harsh",
"lighting": "moonlit blizzard",
"style": "epic cinematic"
},
{
"subGenre": "Mountains",
"scene": "Volcanic summit",
"action": "Prayer ritual",
"camera": "Low angle close-up with sky",
"accents": [
"incense smoke",
"sparks glowing"
],
"mood": "spiritual",
"lighting": "fire glow",
"style": "soft film grain"
}
]
}

View File

@ -50,6 +50,7 @@ async function processVideo(server: any, video: any) {
await sleep(60000);
} else {
logger.error(`All retries failed for video ${video.id} on server ${server.baseUrl}.`);
await query("UPDATE video SET image_path = '' WHERE id = ?", [video.id]);
}
}
}
@ -57,6 +58,7 @@ async function processVideo(server: any, video: any) {
async function worker(server: any) {
while (true) {
await sleep(Math.random() * 3000); // Random delay
const videosToProcess = (await query(
"SELECT * FROM video WHERE image_prompt IS NOT NULL AND (image_path IS NULL OR image_path = '') LIMIT 1"
)) as any[];

View File

@ -68,6 +68,7 @@ async function processVideo(server: any, video: VideoRecord) {
await sleep(60000);
} else {
logger.error(`All retries failed for video ${video.id} on server ${server.baseUrl}.`);
await query("UPDATE video SET video_path = '' WHERE id = ?", [video.id]);
}
}
}
@ -75,8 +76,14 @@ async function processVideo(server: any, video: VideoRecord) {
async function worker(server: any) {
while (true) {
await sleep(Math.random() * 3000); // Random delay
const videosToProcess = (await query(
"SELECT * FROM video WHERE video_prompt IS NOT NULL AND image_path IS NOT NULL AND image_path != 'processing' AND (video_path IS NULL OR video_path = '') LIMIT 1"
`SELECT * FROM video
WHERE video_prompt IS NOT NULL
AND image_path IS NOT NULL
AND image_path != 'processing'
AND (video_path IS NULL OR video_path = '')
ORDER BY RAND() LIMIT 1`
)) as VideoRecord[];
if (videosToProcess.length === 0) {
@ -97,7 +104,7 @@ async function main() {
try {
const promises = servers.map(server => {
if (!server.baseUrl || !server.outputDir) {
logger.warn(`Server is not configured. Skipping.`);
logger.warn(`Server is not configured.Skipping.`);
return Promise.resolve();
}
return worker(server);

154
src/lib/memory-bank.ts Normal file
View File

@ -0,0 +1,154 @@
/**
* memory-bank.ts
*
* Lightweight memory bank utilities.
*
* Provides:
* - initMemoryBank(): create memory-bank dir and initial memories file if missing
* - loadMemories(): read all memories
* - saveMemories(data): overwrite memories file
* - addMemory(entry): append a memory entry and persist
*
* Storage format: memory-bank/memories.json
*
* This file is safe to add to the project even if not used right away.
*/
import { promises as fs } from "fs";
import path from "path";
import { v4 as uuidv4 } from "uuid";
export type MemoryEntry = {
id: string;
type?: string;
content: any;
tags?: string[];
createdAt: string; // ISO
meta?: Record<string, any>;
};
const MEM_DIR = path.join(process.cwd(), "memory-bank");
const MEM_FILE = path.join(MEM_DIR, "memories.json");
type MemFile = {
version: number;
createdAt: string;
entries: MemoryEntry[];
};
async function exists(p: string) {
try {
await fs.access(p);
return true;
} catch {
return false;
}
}
/**
* Ensure memory-bank directory and file exist.
* If the file doesn't exist it will be created with an empty entries array.
*/
export async function initMemoryBank(): Promise<void> {
if (!(await exists(MEM_DIR))) {
await fs.mkdir(MEM_DIR, { recursive: true });
}
if (!(await exists(MEM_FILE))) {
const initial: MemFile = {
version: 1,
createdAt: new Date().toISOString(),
entries: [
{
id: uuidv4(),
type: "system",
content: { message: "memory bank initialized" },
tags: ["init"],
createdAt: new Date().toISOString(),
meta: {},
},
],
};
await fs.writeFile(MEM_FILE, JSON.stringify(initial, null, 2), "utf-8");
}
}
/**
* Load memories.json and return the entries array.
* If the file is missing, initMemoryBank() will be called automatically.
*/
export async function loadMemories(): Promise<MemoryEntry[]> {
if (!(await exists(MEM_FILE))) {
await initMemoryBank();
}
const raw = await fs.readFile(MEM_FILE, "utf-8");
const data: MemFile = JSON.parse(raw);
return data.entries || [];
}
/**
* Overwrite the memories file with the provided entries array.
*/
export async function saveMemories(entries: MemoryEntry[]): Promise<void> {
const payload: MemFile = {
version: 1,
createdAt: new Date().toISOString(),
entries,
};
await fs.writeFile(MEM_FILE, JSON.stringify(payload, null, 2), "utf-8");
}
/**
* Create and persist a new memory entry.
* Returns the created MemoryEntry.
*/
export async function addMemory({
type,
content,
tags,
meta,
}: {
type?: string;
content: any;
tags?: string[];
meta?: Record<string, any>;
}): Promise<MemoryEntry> {
const entries = await loadMemories();
const entry: MemoryEntry = {
id: uuidv4(),
type,
content,
tags: tags || [],
createdAt: new Date().toISOString(),
meta: meta || {},
};
entries.push(entry);
await saveMemories(entries);
return entry;
}
/**
* Simple query helper (in-memory filter).
* Returns matching entries.
*/
export async function findMemories(predicate: (m: MemoryEntry) => boolean): Promise<MemoryEntry[]> {
const entries = await loadMemories();
return entries.filter(predicate);
}
/**
* Example quick-run when this module is invoked directly with ts-node/node.
* (Not executed when imported.)
*/
if (require.main === module) {
(async () => {
try {
await initMemoryBank();
const entries = await loadMemories();
console.log("Memory bank initialized. Entries:", entries.length);
} catch (err) {
console.error("Failed to init memory bank:", err);
process.exit(1);
}
})();
}