You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
3.3 KiB
79 lines
3.3 KiB
import { sqliteTable, text, integer, index } from "drizzle-orm/sqlite-core";
|
|
import { users } from "./auth";
|
|
|
|
// ============ CharacterCard(角色卡定义表)============
|
|
// 独立于 agents 的角色卡体系:以"人设/世界观/开场白/对话示例"为核心,
|
|
// 面向角色扮演场景,与 agent 的工具/审批/记忆注入解耦。
|
|
export const characterCards = sqliteTable(
|
|
"character_cards",
|
|
{
|
|
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
slug: text("slug", { length: 50 }).notNull().unique(),
|
|
name: text("name", { length: 100 }).notNull(),
|
|
avatar: text("avatar"),
|
|
description: text("description"),
|
|
personality: text("personality"),
|
|
scenario: text("scenario"),
|
|
firstMessage: text("first_message"),
|
|
exampleDialogue: text("example_dialogue"),
|
|
systemPrompt: text("system_prompt").notNull().default(""),
|
|
defaultModelId: integer("default_model_id"),
|
|
tags: text("tags"),
|
|
isPublic: integer("is_public").notNull().default(1),
|
|
enabled: integer("enabled").notNull().default(1),
|
|
sortOrder: integer("sort_order").notNull().default(0),
|
|
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
|
|
updatedAt: integer("updated_at", { mode: "timestamp_ms" })
|
|
.defaultNow()
|
|
.$onUpdate(() => new Date())
|
|
.notNull(),
|
|
},
|
|
(table) => [
|
|
index("character_cards_enabled_idx").on(table.enabled),
|
|
index("character_cards_sort_order_idx").on(table.sortOrder),
|
|
],
|
|
);
|
|
|
|
// ============ CharacterSession(角色会话表)============
|
|
export const characterSessions = sqliteTable(
|
|
"character_sessions",
|
|
{
|
|
id: text("id").primaryKey(),
|
|
cardId: integer("card_id").references(() => characterCards.id, { onDelete: "set null" }),
|
|
userId: integer("user_id").references(() => users.id, { onDelete: "cascade" }),
|
|
tempToken: text("temp_token", { length: 64 }),
|
|
title: text("title", { length: 100 }).notNull().default("新对话"),
|
|
modelId: integer("model_id"),
|
|
lastActiveAt: integer("last_active_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
|
|
expiresAt: integer("expires_at", { mode: "timestamp_ms" }),
|
|
deletedAt: integer("deleted_at", { mode: "timestamp_ms" }),
|
|
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
|
|
updatedAt: integer("updated_at", { mode: "timestamp_ms" })
|
|
.defaultNow()
|
|
.$onUpdate(() => new Date())
|
|
.notNull(),
|
|
},
|
|
(table) => [
|
|
index("idx_character_sessions_user_deleted").on(table.userId, table.deletedAt),
|
|
index("idx_character_sessions_temp_token").on(table.tempToken),
|
|
index("idx_character_sessions_card").on(table.cardId),
|
|
],
|
|
);
|
|
|
|
// ============ CharacterMessage(角色消息表)============
|
|
export const characterMessages = sqliteTable(
|
|
"character_messages",
|
|
{
|
|
id: text("id").primaryKey(),
|
|
sessionId: text("session_id")
|
|
.notNull()
|
|
.references(() => characterSessions.id, { onDelete: "cascade" }),
|
|
role: text("role", { length: 20 }).notNull(),
|
|
content: text("content").notNull().default(""),
|
|
sortOrder: integer("sort_order").notNull(),
|
|
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
|
|
},
|
|
(table) => [
|
|
index("idx_character_messages_session_sort").on(table.sessionId, table.sortOrder),
|
|
],
|
|
);
|
|
|