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.
349 lines
8.8 KiB
349 lines
8.8 KiB
import './env';
|
|
import { hash } from "bcryptjs";
|
|
import { dbGlobal } from "./lib/db";
|
|
import { users } from "./lib/schema/auth";
|
|
import { agentTools } from "./lib/schema/agent-tool";
|
|
import { agents, agentToolAssociations, agentSessions, agentMessages, agentMessageFeedback } from "./lib/schema/agent";
|
|
|
|
const DEFAULT_SYSTEM_PROMPT = "You are a helpful AI assistant. Answer questions concisely and accurately. When tools are available, use them proactively to provide better answers.";
|
|
|
|
const CODER_SYSTEM_PROMPT = `You are a professional coding assistant. You help users with programming questions, code review, debugging, and software design.
|
|
|
|
Guidelines:
|
|
- Provide clear, concise, and accurate answers
|
|
- When showing code, use proper markdown code blocks with language tags
|
|
- Proactively use available tools (fetch, search, regex-tester) to gather information when needed
|
|
- Explain your reasoning when making architectural or design decisions
|
|
- If you're unsure, say so rather than guessing
|
|
- Focus on practical, working solutions`;
|
|
|
|
interface ToolSeed {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
description: string;
|
|
type: string;
|
|
config: Record<string, unknown>;
|
|
enabled: number;
|
|
needsApproval: number;
|
|
adminOnly: number;
|
|
sortOrder: number;
|
|
}
|
|
|
|
const TOOLS_SEED: ToolSeed[] = [
|
|
{
|
|
id: "tool_fetch_html",
|
|
name: "fetch_html",
|
|
slug: "fetch_html",
|
|
description: "Fetch a URL and return the HTML content",
|
|
type: "fetch",
|
|
config: { parseMode: "raw", timeout: 30000, allowedDomains: ["*"], blockedDomains: [], maxResponseSize: 102400, defaultMethod: "GET", defaultHeaders: {} },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 10,
|
|
},
|
|
{
|
|
id: "tool_fetch_md",
|
|
name: "fetch_md",
|
|
slug: "fetch_md",
|
|
description: "Fetch a URL and return the content as markdown",
|
|
type: "fetch",
|
|
config: { parseMode: "markdown", timeout: 30000, allowedDomains: ["*"], blockedDomains: [], maxResponseSize: 102400, defaultMethod: "GET", defaultHeaders: {} },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 11,
|
|
},
|
|
{
|
|
id: "tool_fetch_json",
|
|
name: "fetch_json",
|
|
slug: "fetch_json",
|
|
description: "Fetch a URL and return the JSON content",
|
|
type: "fetch",
|
|
config: { parseMode: "json", timeout: 30000, allowedDomains: ["*"], blockedDomains: [], maxResponseSize: 102400, defaultMethod: "GET", defaultHeaders: {} },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 12,
|
|
},
|
|
{
|
|
id: "tool_calculator",
|
|
name: "calculator",
|
|
slug: "calculator",
|
|
description: "Evaluate a mathematical expression",
|
|
type: "calculator",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 20,
|
|
},
|
|
{
|
|
id: "tool_datetime",
|
|
name: "datetime",
|
|
slug: "datetime",
|
|
description: "Get current date and time",
|
|
type: "datetime",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 30,
|
|
},
|
|
{
|
|
id: "tool_uuid",
|
|
name: "uuid",
|
|
slug: "uuid",
|
|
description: "Generate a UUID",
|
|
type: "uuid",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 40,
|
|
},
|
|
{
|
|
id: "tool_base64",
|
|
name: "base64",
|
|
slug: "base64",
|
|
description: "Encode or decode base64 strings",
|
|
type: "base64",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 50,
|
|
},
|
|
{
|
|
id: "tool_json_formatter",
|
|
name: "json-formatter",
|
|
slug: "json-formatter",
|
|
description: "Format and validate JSON strings",
|
|
type: "json-formatter",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 60,
|
|
},
|
|
{
|
|
id: "tool_regex_tester",
|
|
name: "regex-tester",
|
|
slug: "regex-tester",
|
|
description: "Test a regular expression against a string",
|
|
type: "regex-tester",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 70,
|
|
},
|
|
{
|
|
id: "tool_user_info",
|
|
name: "user-info",
|
|
slug: "user-info",
|
|
description: "Get current user information",
|
|
type: "user-info",
|
|
config: {},
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 80,
|
|
},
|
|
{
|
|
id: "tool_search",
|
|
name: "search",
|
|
slug: "search",
|
|
description: "Search the web for information",
|
|
type: "search",
|
|
config: { maxResults: 5 },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 90,
|
|
},
|
|
{
|
|
id: "tool_hash",
|
|
name: "hash",
|
|
slug: "hash",
|
|
description: "Compute hash (md5/sha1/sha256/sha512) or compare hashes",
|
|
type: "hash",
|
|
config: { defaultAlgorithm: "sha256", uppercase: false },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 100,
|
|
},
|
|
{
|
|
id: "tool_color",
|
|
name: "color",
|
|
slug: "color",
|
|
description: "Color conversion (hex/rgb/hsl), random color, mix colors, WCAG contrast",
|
|
type: "color",
|
|
config: { defaultFormat: "hex" },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 110,
|
|
},
|
|
{
|
|
id: "tool_dice",
|
|
name: "dice",
|
|
slug: "dice",
|
|
description: "Roll dice, flip coin, pick from list, or play rock-paper-scissors",
|
|
type: "dice",
|
|
config: { defaultSides: 6 },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 120,
|
|
},
|
|
{
|
|
id: "tool_magic_8ball",
|
|
name: "magic-8ball",
|
|
slug: "magic-8ball",
|
|
description: "Magic 8-Ball fortune telling and daily fortune",
|
|
type: "magic-8ball",
|
|
config: { language: "zh" },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 130,
|
|
},
|
|
{
|
|
id: "tool_guess_who",
|
|
name: "guess-who",
|
|
slug: "guess-who",
|
|
description: "Guess who game - AI guesses your character or you guess AI's character",
|
|
type: "guess-who",
|
|
config: { language: "zh", maxQuestions: 20, difficulty: "medium" },
|
|
enabled: 1,
|
|
needsApproval: 0,
|
|
adminOnly: 0,
|
|
sortOrder: 140,
|
|
},
|
|
{
|
|
id: "tool_document",
|
|
name: "document",
|
|
slug: "document",
|
|
description: "创建、读取、更新、删除和列出文档,用于记忆管理和交付物产出",
|
|
type: "document",
|
|
config: {
|
|
approvalRequiredActions: ["delete"],
|
|
maxContentLength: 10000,
|
|
defaultTokenBudget: 2000,
|
|
maxListSize: 20,
|
|
},
|
|
enabled: 1,
|
|
needsApproval: 1,
|
|
adminOnly: 0,
|
|
sortOrder: 150,
|
|
},
|
|
];
|
|
|
|
async function seedTools() {
|
|
for (const t of TOOLS_SEED) {
|
|
await dbGlobal.insert(agentTools).values({
|
|
id: t.id,
|
|
name: t.name,
|
|
slug: t.slug,
|
|
description: t.description,
|
|
type: t.type,
|
|
config: JSON.stringify(t.config),
|
|
enabled: t.enabled,
|
|
needsApproval: t.needsApproval,
|
|
adminOnly: t.adminOnly,
|
|
sortOrder: t.sortOrder,
|
|
});
|
|
}
|
|
console.log(`Seeded ${TOOLS_SEED.length} tools`);
|
|
}
|
|
|
|
async function seedAgents() {
|
|
const [defaultAgent] = await dbGlobal
|
|
.insert(agents)
|
|
.values({
|
|
slug: "default",
|
|
name: "默认助手",
|
|
description: "通用 AI 助手",
|
|
systemPrompt: DEFAULT_SYSTEM_PROMPT,
|
|
titleStrategy: "llm",
|
|
enableThinking: 0,
|
|
enableTools: 1,
|
|
maxStepCount: 6,
|
|
isDefault: 1,
|
|
isCallable: 0,
|
|
sortOrder: 0,
|
|
enabled: 1,
|
|
})
|
|
.returning();
|
|
|
|
const [coderAgent] = await dbGlobal
|
|
.insert(agents)
|
|
.values({
|
|
slug: "coder",
|
|
name: "编程助手",
|
|
description: "专注于编程问题的 AI 助手",
|
|
systemPrompt: CODER_SYSTEM_PROMPT,
|
|
titleStrategy: "first-line",
|
|
enableThinking: 1,
|
|
enableTools: 1,
|
|
maxStepCount: 12,
|
|
isDefault: 0,
|
|
isCallable: 1,
|
|
sortOrder: 10,
|
|
enabled: 1,
|
|
})
|
|
.returning();
|
|
|
|
console.log("Seeded 2 agents: default, coder");
|
|
|
|
const allToolIds = TOOLS_SEED.map((t) => t.id);
|
|
const coderToolIds = ["tool_fetch_md", "tool_search", "tool_regex_tester"];
|
|
|
|
for (let i = 0; i < allToolIds.length; i++) {
|
|
await dbGlobal.insert(agentToolAssociations).values({
|
|
agentId: defaultAgent.id,
|
|
toolId: allToolIds[i],
|
|
sortOrder: i,
|
|
});
|
|
}
|
|
|
|
for (let i = 0; i < coderToolIds.length; i++) {
|
|
await dbGlobal.insert(agentToolAssociations).values({
|
|
agentId: coderAgent.id,
|
|
toolId: coderToolIds[i],
|
|
sortOrder: i,
|
|
});
|
|
}
|
|
|
|
console.log(`Seeded ${allToolIds.length} tool associations for default agent`);
|
|
console.log(`Seeded ${coderToolIds.length} tool associations for coder agent`);
|
|
}
|
|
|
|
async function seedAdmin() {
|
|
const password = await hash("123456qaz", 10);
|
|
await dbGlobal.insert(users).values({
|
|
username: "admin",
|
|
password,
|
|
role: "admin",
|
|
status: "active",
|
|
nickname: "管理员",
|
|
});
|
|
console.log("Seeded admin user (admin / 123456qaz)");
|
|
}
|
|
|
|
async function main() {
|
|
await seedAdmin();
|
|
await seedTools();
|
|
await seedAgents();
|
|
|
|
console.log("Seed complete!");
|
|
process.exit(0);
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|
|
|