@unified-llm/core
Version:
Unified LLM interface (in-memory).
181 lines • 7.49 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDatabase = exports.DatabaseManager = void 0;
const client_1 = require("@libsql/client");
const drizzle_orm_1 = require("drizzle-orm");
const libsql_1 = require("drizzle-orm/libsql");
const migrator_1 = require("drizzle-orm/libsql/migrator");
const schema = __importStar(require("./schema"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
class DatabaseManager {
// --- コンストラクタは async にする ------------------------------
constructor(client) {
this.client = client;
this.db = (0, libsql_1.drizzle)(client, { schema });
}
/** Factory: インスタンス取得 & 1 回だけ migrate */
static async getInstance(dbFile) {
let finalPath;
if (dbFile) {
// 明示的にパスが指定された場合は常に作成
finalPath = dbFile;
}
else if (process.env.UNIFIED_LLM_DB_PATH) {
// 環境変数が設定されている場合は使用
finalPath = process.env.UNIFIED_LLM_DB_PATH;
}
else {
// どちらもない場合はnullを返す(persistence disabled)
return null;
}
if (DatabaseManager.instances.has(finalPath)) {
const existingInstance = DatabaseManager.instances.get(finalPath);
if (existingInstance) {
return existingInstance;
}
}
// ファイル用 URL。ディレクトリは手動で作る
const url = finalPath.startsWith('file:') ? finalPath : `file:${finalPath}`;
fs_1.default.mkdirSync(path_1.default.dirname(finalPath), { recursive: true });
const client = (0, client_1.createClient)({ url }); // ← ネイティブ依存なし
const mgr = new DatabaseManager(client);
// マイグレーション(非同期)
const migrationsFolder = path_1.default.join(__dirname, '../../drizzle');
if (fs_1.default.existsSync(migrationsFolder)) {
await (0, migrator_1.migrate)(mgr.db, { migrationsFolder });
}
else {
await mgr.createTables(); // fallback
}
DatabaseManager.instances.set(finalPath, mgr);
return mgr;
}
/** drizzle インスタンスを返す */
getDb() {
return this.db;
}
/** libsql の close は Promise */
async close() {
this.client.close();
}
// --- Fallback: raw SQL 実行は execute ----------------------------
async createTables() {
// Execute each table creation separately to avoid issues with multiple statements
const statements = [
`CREATE TABLE IF NOT EXISTS threads (
id TEXT PRIMARY KEY,
title TEXT,
description TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
created_by TEXT,
is_active INTEGER DEFAULT 1,
tags TEXT,
metadata TEXT
)`,
`CREATE TABLE IF NOT EXISTS llm_clients (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
provider TEXT NOT NULL,
model TEXT,
system_prompt TEXT,
instructions TEXT,
api_key TEXT,
generation_config TEXT,
tools TEXT,
argument_map TEXT,
tags TEXT,
is_active INTEGER DEFAULT 1,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
metadata TEXT
)`,
`CREATE TABLE IF NOT EXISTS thread_participants (
id TEXT PRIMARY KEY,
thread_id TEXT NOT NULL,
client_id TEXT NOT NULL,
joined_at INTEGER NOT NULL,
left_at INTEGER,
role TEXT DEFAULT 'participant',
nickname TEXT,
metadata TEXT,
FOREIGN KEY (thread_id) REFERENCES threads(id) ON DELETE CASCADE,
FOREIGN KEY (client_id) REFERENCES llm_clients(id) ON DELETE CASCADE
)`,
`CREATE TABLE IF NOT EXISTS messages (
id TEXT PRIMARY KEY,
thread_id TEXT,
client_id TEXT,
role TEXT NOT NULL,
content TEXT NOT NULL,
tool_calls TEXT,
tool_results TEXT,
timestamp INTEGER NOT NULL,
sequence INTEGER,
parent_message_id TEXT,
is_edited INTEGER DEFAULT 0,
edited_at INTEGER,
tokens INTEGER,
cost REAL,
metadata TEXT,
FOREIGN KEY (thread_id) REFERENCES threads(id) ON DELETE CASCADE,
FOREIGN KEY (client_id) REFERENCES llm_clients(id)
)`,
`CREATE INDEX IF NOT EXISTS idx_messages_thread_id ON messages(thread_id)`,
`CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(timestamp)`,
`CREATE INDEX IF NOT EXISTS idx_messages_client_id ON messages(client_id)`,
`CREATE INDEX IF NOT EXISTS idx_thread_participants_thread_id ON thread_participants(thread_id)`,
`CREATE INDEX IF NOT EXISTS idx_thread_participants_client_id ON thread_participants(client_id)`
];
for (const statement of statements) {
await this.db.run(drizzle_orm_1.sql.raw(statement));
}
}
}
exports.DatabaseManager = DatabaseManager;
DatabaseManager.instances = new Map();
/** 以前呼び出していた util も Promise に */
const getDatabase = async (dbPath) => {
const manager = await DatabaseManager.getInstance(dbPath);
return manager ? manager.getDb() : null;
};
exports.getDatabase = getDatabase;
//# sourceMappingURL=connection.js.map