174 lines
6.8 KiB
JavaScript
174 lines
6.8 KiB
JavaScript
import mysql from 'mysql2/promise';
|
|
|
|
async function main() {
|
|
const conn = await mysql.createConnection(process.env.DATABASE_URL);
|
|
|
|
const statements = [
|
|
// agentAccessControl
|
|
`CREATE TABLE IF NOT EXISTS \`agentAccessControl\` (
|
|
\`id\` int AUTO_INCREMENT NOT NULL,
|
|
\`agentId\` int NOT NULL,
|
|
\`tool\` varchar(50) NOT NULL,
|
|
\`isAllowed\` boolean DEFAULT true,
|
|
\`maxExecutionsPerHour\` int DEFAULT 100,
|
|
\`timeoutSeconds\` int DEFAULT 30,
|
|
\`allowedPatterns\` json,
|
|
\`blockedPatterns\` json,
|
|
\`createdAt\` timestamp NOT NULL DEFAULT (now()),
|
|
\`updatedAt\` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP,
|
|
CONSTRAINT \`agentAccessControl_id\` PRIMARY KEY(\`id\`)
|
|
)`,
|
|
|
|
// agentMetrics
|
|
`CREATE TABLE IF NOT EXISTS \`agentMetrics\` (
|
|
\`id\` int AUTO_INCREMENT NOT NULL,
|
|
\`agentId\` int NOT NULL,
|
|
\`requestId\` varchar(64) NOT NULL,
|
|
\`userMessage\` text,
|
|
\`agentResponse\` text,
|
|
\`inputTokens\` int DEFAULT 0,
|
|
\`outputTokens\` int DEFAULT 0,
|
|
\`totalTokens\` int DEFAULT 0,
|
|
\`processingTimeMs\` int NOT NULL,
|
|
\`status\` enum('success','error','timeout','rate_limited') NOT NULL,
|
|
\`errorMessage\` text,
|
|
\`toolsCalled\` json,
|
|
\`model\` varchar(100),
|
|
\`temperature\` decimal(3,2),
|
|
\`createdAt\` timestamp NOT NULL DEFAULT (now()),
|
|
CONSTRAINT \`agentMetrics_id\` PRIMARY KEY(\`id\`),
|
|
CONSTRAINT \`agentMetrics_requestId_unique\` UNIQUE(\`requestId\`)
|
|
)`,
|
|
|
|
// agents — full schema with isSystem and isOrchestrator
|
|
`CREATE TABLE IF NOT EXISTS \`agents\` (
|
|
\`id\` int AUTO_INCREMENT NOT NULL,
|
|
\`userId\` int NOT NULL,
|
|
\`name\` varchar(255) NOT NULL,
|
|
\`description\` text,
|
|
\`role\` varchar(100) NOT NULL,
|
|
\`model\` varchar(100) NOT NULL,
|
|
\`provider\` varchar(50) NOT NULL,
|
|
\`temperature\` decimal(3,2) DEFAULT '0.7',
|
|
\`maxTokens\` int DEFAULT 2048,
|
|
\`topP\` decimal(3,2) DEFAULT '1.0',
|
|
\`frequencyPenalty\` decimal(3,2) DEFAULT '0.0',
|
|
\`presencePenalty\` decimal(3,2) DEFAULT '0.0',
|
|
\`systemPrompt\` text,
|
|
\`allowedTools\` json,
|
|
\`allowedDomains\` json,
|
|
\`maxRequestsPerHour\` int DEFAULT 100,
|
|
\`isActive\` boolean DEFAULT true,
|
|
\`isPublic\` boolean DEFAULT false,
|
|
\`isSystem\` boolean DEFAULT false,
|
|
\`isOrchestrator\` boolean DEFAULT false,
|
|
\`tags\` json,
|
|
\`metadata\` json,
|
|
\`createdAt\` timestamp NOT NULL DEFAULT (now()),
|
|
\`updatedAt\` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP,
|
|
CONSTRAINT \`agents_id\` PRIMARY KEY(\`id\`)
|
|
)`,
|
|
|
|
// toolDefinitions
|
|
`CREATE TABLE IF NOT EXISTS \`toolDefinitions\` (
|
|
\`id\` int AUTO_INCREMENT NOT NULL,
|
|
\`toolId\` varchar(100) NOT NULL,
|
|
\`name\` varchar(255) NOT NULL,
|
|
\`description\` text NOT NULL,
|
|
\`category\` varchar(50) NOT NULL DEFAULT 'custom',
|
|
\`dangerous\` boolean DEFAULT false,
|
|
\`parameters\` json,
|
|
\`implementation\` text NOT NULL,
|
|
\`isActive\` boolean DEFAULT true,
|
|
\`createdBy\` int,
|
|
\`createdAt\` timestamp NOT NULL DEFAULT (now()),
|
|
\`updatedAt\` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP,
|
|
CONSTRAINT \`toolDefinitions_id\` PRIMARY KEY(\`id\`),
|
|
CONSTRAINT \`toolDefinitions_toolId_unique\` UNIQUE(\`toolId\`)
|
|
)`,
|
|
|
|
// browserSessions
|
|
`CREATE TABLE IF NOT EXISTS \`browserSessions\` (
|
|
\`id\` int AUTO_INCREMENT NOT NULL,
|
|
\`sessionId\` varchar(64) NOT NULL,
|
|
\`agentId\` int NOT NULL,
|
|
\`currentUrl\` text,
|
|
\`title\` text,
|
|
\`status\` enum('active','idle','closed','error') DEFAULT 'idle',
|
|
\`screenshotUrl\` text,
|
|
\`lastActionAt\` timestamp DEFAULT (now()),
|
|
\`createdAt\` timestamp NOT NULL DEFAULT (now()),
|
|
\`closedAt\` timestamp,
|
|
CONSTRAINT \`browserSessions_id\` PRIMARY KEY(\`id\`),
|
|
CONSTRAINT \`browserSessions_sessionId_unique\` UNIQUE(\`sessionId\`)
|
|
)`,
|
|
|
|
// agentHistory — conversation history per agent
|
|
`CREATE TABLE IF NOT EXISTS \`agentHistory\` (
|
|
\`id\` int AUTO_INCREMENT NOT NULL,
|
|
\`agentId\` int NOT NULL,
|
|
\`sessionId\` varchar(64),
|
|
\`role\` enum('user','assistant','system','tool') NOT NULL,
|
|
\`content\` text NOT NULL,
|
|
\`toolCalls\` json,
|
|
\`metadata\` json,
|
|
\`createdAt\` timestamp NOT NULL DEFAULT (now()),
|
|
CONSTRAINT \`agentHistory_id\` PRIMARY KEY(\`id\`)
|
|
)`,
|
|
|
|
// Indexes
|
|
`CREATE INDEX IF NOT EXISTS \`agentAccessControl_agentId_tool_idx\` ON \`agentAccessControl\` (\`agentId\`,\`tool\`)`,
|
|
`CREATE INDEX IF NOT EXISTS \`agentMetrics_agentId_idx\` ON \`agentMetrics\` (\`agentId\`)`,
|
|
`CREATE INDEX IF NOT EXISTS \`agentMetrics_createdAt_idx\` ON \`agentMetrics\` (\`createdAt\`)`,
|
|
`CREATE INDEX IF NOT EXISTS \`agents_userId_idx\` ON \`agents\` (\`userId\`)`,
|
|
`CREATE INDEX IF NOT EXISTS \`agents_model_idx\` ON \`agents\` (\`model\`)`,
|
|
`CREATE INDEX IF NOT EXISTS \`browserSessions_agentId_idx\` ON \`browserSessions\` (\`agentId\`)`,
|
|
`CREATE INDEX IF NOT EXISTS \`agentHistory_agentId_idx\` ON \`agentHistory\` (\`agentId\`)`,
|
|
];
|
|
|
|
for (const stmt of statements) {
|
|
try {
|
|
await conn.query(stmt);
|
|
const tableName = stmt.match(/TABLE.*?`(\w+)`/)?.[1] || stmt.match(/INDEX.*?ON `(\w+)`/)?.[1] || 'statement';
|
|
console.log('✓', tableName);
|
|
} catch (e) {
|
|
if (e.code === 'ER_DUP_KEYNAME' || e.message.includes('Duplicate key name')) {
|
|
console.log('⚠ Index already exists (ok)');
|
|
} else if (e.message.includes('already exists')) {
|
|
console.log('⚠ Already exists (ok)');
|
|
} else {
|
|
console.error('✗ Error:', e.message.slice(0, 120));
|
|
}
|
|
}
|
|
}
|
|
|
|
// ALTER TABLE to add missing columns to existing tables
|
|
const alterStatements = [
|
|
`ALTER TABLE \`agents\` ADD COLUMN IF NOT EXISTS \`isSystem\` boolean DEFAULT false`,
|
|
`ALTER TABLE \`agents\` ADD COLUMN IF NOT EXISTS \`isOrchestrator\` boolean DEFAULT false`,
|
|
];
|
|
|
|
console.log('\n--- Applying ALTER TABLE migrations ---');
|
|
for (const stmt of alterStatements) {
|
|
try {
|
|
await conn.query(stmt);
|
|
const col = stmt.match(/ADD COLUMN.*?`(\w+)`/)?.[1] || 'column';
|
|
console.log('✓ Added column:', col);
|
|
} catch (e) {
|
|
if (e.message.includes('Duplicate column name') || e.message.includes('already exists')) {
|
|
const col = stmt.match(/ADD COLUMN.*?`(\w+)`/)?.[1] || 'column';
|
|
console.log('⚠ Column already exists:', col, '(ok)');
|
|
} else {
|
|
console.error('✗ ALTER error:', e.message.slice(0, 120));
|
|
}
|
|
}
|
|
}
|
|
|
|
const [tables] = await conn.query('SHOW TABLES');
|
|
console.log('\n✅ All tables:', tables.map(t => Object.values(t)[0]).join(', '));
|
|
|
|
await conn.end();
|
|
}
|
|
|
|
main().catch(console.error);
|