规定数据类型

This commit is contained in:
2026-04-24 01:45:41 +08:00
parent d1943f564a
commit 35eff3faf6
86 changed files with 3809 additions and 0 deletions

1
shared/schemas/.gitkeep Normal file
View File

@@ -0,0 +1 @@
// Zod Schemas for Validation (v3)

6
shared/schemas/index.ts Normal file
View File

@@ -0,0 +1,6 @@
/**
* Shared Schemas 导出
*/
export * from './sillytavern.schemas';
export * from './internal.schemas';

View File

@@ -0,0 +1,258 @@
/**
* Zod Schemas - 项目内部格式验证
*/
import { z } from 'zod';
// ==================== 世界书条目 ====================
export const ActivationTypeSchema = z.enum([
'permanent',
'keyword',
'rag',
'logic',
]);
export const LogicOperatorSchema = z.enum([
'equals',
'not_equals',
'contains',
'not_contains',
'greater',
'less',
]);
export const LogicExpressionSchema = z.object({
variable1: z.string(),
operator: LogicOperatorSchema,
variable2: z.string(),
});
export const RAGConfigSchema = z.object({
libraryId: z.string(),
threshold: z.number().min(0).max(1).optional(),
maxEntries: z.number().min(1).optional(),
});
export const WorldInfoEntrySchema = z.object({
uid: z.string(),
key: z.array(z.string()).optional(),
keysecondary: z.array(z.string()).optional(),
content: z.string(),
order: z.number(),
position: z.enum([
'before_char',
'after_char',
'before_example',
'after_example',
'author_note_top',
'author_note_bottom',
'at_depth',
]),
depth: z.number().optional(),
role: z.enum(['system', 'user', 'assistant']).optional(),
probability: z.number().min(0).max(100).optional(),
group: z.array(z.string()).optional(),
groupPrioritize: z.boolean().optional(),
useGroupScoring: z.boolean().optional(),
automationId: z.string().optional(),
disable: z.boolean().optional(),
extensions: z.record(z.unknown()).optional(),
// 自定义字段
activationType: ActivationTypeSchema,
logicExpression: LogicExpressionSchema.optional(),
ragConfig: RAGConfigSchema.optional(),
createdAt: z.number(),
updatedAt: z.number(),
});
export const WorldInfoSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string().optional(),
entries: z.array(WorldInfoEntrySchema),
createdAt: z.number(),
updatedAt: z.number(),
version: z.number(),
});
// ==================== 角色卡 ====================
export const OutputSchemaFieldTypeSchema = z.enum([
'string',
'number',
'boolean',
'array',
'object',
]);
export const OutputSchemaFieldSchema: z.ZodType<any> = z.lazy(() =>
z.object({
name: z.string(),
type: OutputSchemaFieldTypeSchema,
description: z.string(),
required: z.boolean().optional(),
enum: z.array(z.string()).optional(),
fields: z.array(OutputSchemaFieldSchema).optional(),
})
);
export const CharacterCardSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string(),
personality: z.string(),
scenario: z.string(),
first_mes: z.string(),
mes_example: z.string(),
alternate_greetings: z.array(z.string()).optional(),
creator_notes: z.string().optional(),
system_prompt: z.string().optional(),
post_history_instructions: z.string().optional(),
tags: z.array(z.string()).optional(),
// 自定义字段
categories: z.array(z.string()),
worldInfoId: z.string().optional(),
outputSchema: z.array(OutputSchemaFieldSchema).optional(),
avatarPath: z.string().optional(),
createdAt: z.number(),
updatedAt: z.number(),
lastChatAt: z.number().optional(),
isFavorite: z.boolean(),
version: z.number(),
});
// ==================== 聊天记录 ====================
export const ChatHeaderSchema = z.object({
id: z.string(),
displayName: z.string(),
characterId: z.string(),
userName: z.string(),
characterName: z.string(),
tableData: z.record(z.unknown()).optional(),
createdAt: z.number(),
updatedAt: z.number(),
messageCount: z.number(),
});
export const ChatMessageSchema = z.object({
id: z.string(),
chatId: z.string(),
name: z.string(),
is_user: z.boolean(),
is_system: z.boolean().optional(),
sendDate: z.string(),
mes: z.string(),
swipes: z.array(z.string()).optional(),
swipe_id: z.number().optional(),
is_hidden: z.boolean().optional(),
extra: z.record(z.unknown()).optional(),
tokenCount: z.number().optional(),
isTemporary: z.boolean().optional(),
});
export const ChatLogSchema = z.object({
header: ChatHeaderSchema,
messages: z.array(ChatMessageSchema),
});
// ==================== 预设 ====================
export const GenerationPresetSchema = z.object({
id: z.string(),
name: z.string(),
temperature: z.number(),
topP: z.number(),
topK: z.number(),
repetitionPenalty: z.number(),
frequencyPenalty: z.number().optional(),
presencePenalty: z.number().optional(),
maxLength: z.number().optional(),
isDefault: z.boolean(),
createdAt: z.number(),
updatedAt: z.number(),
});
// ==================== 提示词预设 (Prompt Preset) ====================
export const PromptRoleSchema = z.enum(['system', 'ai', 'user']);
export const PromptEntrySchema = z.object({
identifier: z.string(),
name: z.string(),
enabled: z.boolean(),
content: z.string(),
order: z.number(),
role: PromptRoleSchema,
tokenCount: z.number(),
isSystemNode: z.boolean(),
});
export const PromptPresetViewSchema = z.object({
characterId: z.string(),
entries: z.array(PromptEntrySchema),
updatedAt: z.number(),
version: z.number(),
});
// ==================== 工作流 ====================
export const WorkflowNodeTypeSchema = z.enum([
'llm_call',
'condition',
'data_process',
'parallel',
'merge',
]);
export const WorkflowNodeSchema = z.object({
id: z.string(),
type: WorkflowNodeTypeSchema,
name: z.string(),
config: z.record(z.unknown()),
inputMapping: z.record(z.string()).optional(),
outputMapping: z.record(z.string()).optional(),
});
export const WorkflowEdgeSchema = z.object({
id: z.string(),
source: z.string(),
target: z.string(),
sourcePort: z.string().optional(),
targetPort: z.string().optional(),
});
export const WorkflowSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string().optional(),
nodes: z.array(WorkflowNodeSchema),
edges: z.array(WorkflowEdgeSchema),
entryNodeId: z.string(),
createdAt: z.number(),
updatedAt: z.number(),
version: z.number(),
});
// ==================== RAG 库 ====================
export const RAGDocumentSchema = z.object({
id: z.string(),
content: z.string(),
metadata: z.record(z.unknown()).optional(),
embedding: z.array(z.number()).optional(),
createdAt: z.number(),
});
export const RAGLibrarySchema = z.object({
id: z.string(),
name: z.string(),
description: z.string().optional(),
documents: z.array(RAGDocumentSchema),
embeddingModel: z.string().optional(),
createdAt: z.number(),
updatedAt: z.number(),
});

View File

@@ -0,0 +1,157 @@
/**
* Zod Schemas - SillyTavern 兼容格式验证
*/
import { z } from 'zod';
// ==================== 世界书条目 ====================
export const STWorldInfoEntryPositionSchema = z.enum([
'before_char',
'after_char',
'before_example',
'after_example',
'author_note_top',
'author_note_bottom',
'at_depth',
]);
export const STWorldInfoFilterLogicSchema = z.enum([
'and_any',
'and_all',
'not_any',
'not_all',
]);
export const STWorldInfoEntryRoleSchema = z.enum([
'system',
'user',
'assistant',
]);
export const STWorldInfoEntrySchema = z.object({
uid: z.string(),
key: z.array(z.string()).optional(),
keysecondary: z.array(z.string()).optional(),
filter: STWorldInfoFilterLogicSchema.optional(),
content: z.string(),
constant: z.boolean().optional(),
selective: z.boolean().optional(),
order: z.number(),
position: STWorldInfoEntryPositionSchema,
depth: z.number().optional(),
role: STWorldInfoEntryRoleSchema.optional(),
probability: z.number().min(0).max(100).optional(),
group: z.array(z.string()).optional(),
groupPrioritize: z.boolean().optional(),
useGroupScoring: z.boolean().optional(),
automationId: z.string().optional(),
disable: z.boolean().optional(),
extensions: z.record(z.unknown()).optional(),
});
export const STWorldInfoSchema = z.object({
spec: z.string(),
name: z.string().optional(),
description: z.string().optional(),
entries: z.array(STWorldInfoEntrySchema),
extensions: z.record(z.unknown()).optional(),
});
// ==================== 角色卡 ====================
export const STCharacterCardSpecSchema = z.enum([
'chara_card_v1',
'chara_card_v2',
'chara_card_v3',
]);
export const STCharacterCardDataSchema = z.object({
name: z.string(),
description: z.string(),
personality: z.string(),
scenario: z.string(),
first_mes: z.string(),
mes_example: z.string(),
alternate_greetings: z.array(z.string()).optional(),
creator_notes: z.string().optional(),
system_prompt: z.string().optional(),
post_history_instructions: z.string().optional(),
tags: z.array(z.string()).optional(),
character_book: STWorldInfoSchema.optional(),
extensions: z.object({
world: z.string().optional(),
talkativeness: z.number().min(0).max(1).optional(),
fav: z.boolean().optional(),
}).passthrough().optional(),
});
export const STCharacterCardSchema = z.object({
spec: STCharacterCardSpecSchema,
spec_version: z.string().optional(),
data: STCharacterCardDataSchema,
});
// ==================== 聊天记录 ====================
export const STChatHeaderSchema = z.object({
user_name: z.string(),
character_name: z.string(),
create_date: z.string(),
chat_metadata: z.record(z.unknown()).optional(),
}).passthrough();
export const STChatMessageSchema = z.object({
name: z.string(),
is_user: z.boolean(),
is_system: z.boolean().optional(),
send_date: z.union([z.number(), z.string()]),
mes: z.string(),
swipes: z.array(z.string()).optional(),
swipe_id: z.number().optional(),
is_hidden: z.boolean().optional(),
extra: z.record(z.unknown()).optional(),
});
// ==================== 预设 ====================
export const STGenerationPresetSchema = z.object({
name: z.string(),
temperature: z.number().optional(),
top_p: z.number().optional(),
top_k: z.number().optional(),
repetition_penalty: z.number().optional(),
frequency_penalty: z.number().optional(),
presence_penalty: z.number().optional(),
max_length: z.number().optional(),
}).passthrough();
// ==================== 提示词预设 (Prompt Preset) ====================
export const STPromptRoleSchema = z.enum(['system', 'assistant', 'user']);
export const STPromptSchema = z.object({
identifier: z.string(),
name: z.string().optional(),
content: z.string(),
role: STPromptRoleSchema,
marker: z.boolean().optional(),
injection_order: z.number().optional(),
extensions: z.record(z.unknown()).optional(),
});
export const STPromptOrderItemSchema = z.object({
identifier: z.string(),
enabled: z.boolean(),
});
export const STPromptOrderConfigSchema = z.object({
order: z.array(STPromptOrderItemSchema),
});
export const STPromptPresetSchema = z.object({
name: z.string(),
prompts: z.array(STPromptSchema),
prompt_order: z.record(STPromptOrderConfigSchema),
default_prompt_order: STPromptOrderConfigSchema.optional(),
});