kit初版,模型引入,agent优化

This commit is contained in:
2026-04-13 00:41:23 +08:00
parent 9b053e302b
commit c435ab15cf
14097 changed files with 5032 additions and 2676248 deletions

View File

@@ -0,0 +1,160 @@
/**
* 基于 localStorage 的客户端持久化存储。
* 提供会话、标签、图片资源的 CRUD 操作。
*/
import type { Session, Tag, ImageAsset, ChatMessage } from "./types";
const STORAGE_KEYS = {
sessions: "epeekit-sessions",
tags: "epeekit-tags",
assets: "epeekit-assets",
} as const;
// --------------- 内置标签 ---------------
const BUILTIN_TAGS: Tag[] = [
{ id: "tag-ui", name: "UI", color: "#6366f1", builtin: true },
{ id: "tag-icon", name: "Icon", color: "#f59e0b", builtin: true },
{ id: "tag-illustration", name: "原画", color: "#10b981", builtin: true },
{ id: "tag-style", name: "风格探索", color: "#ec4899", builtin: true },
{ id: "tag-character", name: "立绘", color: "#8b5cf6", builtin: true },
{ id: "tag-concept", name: "概念图", color: "#06b6d4", builtin: true },
];
// --------------- 通用 helpers ---------------
function readJSON<T>(key: string, fallback: T): T {
if (typeof window === "undefined") return fallback;
try {
const raw = localStorage.getItem(key);
return raw ? (JSON.parse(raw) as T) : fallback;
} catch {
return fallback;
}
}
function writeJSON<T>(key: string, data: T) {
if (typeof window === "undefined") return;
localStorage.setItem(key, JSON.stringify(data));
}
// --------------- ID 生成 ---------------
let counter = 0;
export function generateId(prefix = ""): string {
counter++;
const ts = Date.now().toString(36);
const rand = Math.random().toString(36).slice(2, 6);
return `${prefix}${ts}-${rand}-${counter}`;
}
// --------------- 标签 ---------------
export function loadTags(): Tag[] {
const custom = readJSON<Tag[]>(STORAGE_KEYS.tags, []);
const builtinIds = new Set(BUILTIN_TAGS.map((t) => t.id));
const merged = [...BUILTIN_TAGS, ...custom.filter((t) => !builtinIds.has(t.id))];
return merged;
}
export function saveTags(tags: Tag[]) {
const custom = tags.filter((t) => !t.builtin);
writeJSON(STORAGE_KEYS.tags, custom);
}
export function addTag(name: string, color: string): Tag {
const tag: Tag = { id: generateId("tag-"), name, color, builtin: false };
const existing = loadTags();
saveTags([...existing, tag]);
return tag;
}
export function deleteTag(tagId: string) {
const tags = loadTags().filter((t) => t.id !== tagId && !t.builtin);
saveTags(tags);
}
// --------------- 会话 ---------------
export function loadSessions(): Session[] {
return readJSON<Session[]>(STORAGE_KEYS.sessions, []);
}
export function saveSessions(sessions: Session[]) {
writeJSON(STORAGE_KEYS.sessions, sessions);
}
export function createSession(): Session {
const now = Date.now();
const session: Session = {
id: generateId("sess-"),
title: "新对话",
tags: [],
messages: [],
createdAt: now,
updatedAt: now,
};
const sessions = loadSessions();
saveSessions([session, ...sessions]);
return session;
}
export function updateSession(session: Session) {
const sessions = loadSessions();
const idx = sessions.findIndex((s) => s.id === session.id);
if (idx >= 0) {
sessions[idx] = { ...session, updatedAt: Date.now() };
} else {
sessions.unshift({ ...session, updatedAt: Date.now() });
}
saveSessions(sessions);
}
export function deleteSession(sessionId: string) {
const sessions = loadSessions().filter((s) => s.id !== sessionId);
saveSessions(sessions);
// 同时删除关联的图片资源
const assets = loadAssets().filter((a) => a.sessionId !== sessionId);
saveAssets(assets);
}
// --------------- 图片资源 ---------------
export function loadAssets(): ImageAsset[] {
return readJSON<ImageAsset[]>(STORAGE_KEYS.assets, []);
}
export function saveAssets(assets: ImageAsset[]) {
writeJSON(STORAGE_KEYS.assets, assets);
}
export function addAsset(asset: ImageAsset) {
const assets = loadAssets();
assets.unshift(asset);
saveAssets(assets);
}
export function updateAsset(assetId: string, patch: Partial<ImageAsset>) {
const assets = loadAssets();
const idx = assets.findIndex((a) => a.id === assetId);
if (idx >= 0) {
assets[idx] = { ...assets[idx], ...patch };
saveAssets(assets);
}
}
export function deleteAsset(assetId: string) {
saveAssets(loadAssets().filter((a) => a.id !== assetId));
}
export function toggleFavorite(assetId: string): boolean {
const assets = loadAssets();
const idx = assets.findIndex((a) => a.id === assetId);
if (idx >= 0) {
assets[idx].favorited = !assets[idx].favorited;
saveAssets(assets);
return assets[idx].favorited;
}
return false;
}