@hasna/brains 0.0.1 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp/index.js CHANGED
@@ -15,7 +15,6 @@ var __toESM = (mod, isNodeMode, target) => {
15
15
  });
16
16
  return to;
17
17
  };
18
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
18
  var __export = (target, all) => {
20
19
  for (var name in all)
21
20
  __defProp(target, name, {
@@ -27,771 +26,6 @@ var __export = (target, all) => {
27
26
  };
28
27
  var __require = import.meta.require;
29
28
 
30
- // node_modules/better-sqlite3/lib/util.js
31
- var require_util = __commonJS((exports) => {
32
- exports.getBooleanOption = (options, key) => {
33
- let value = false;
34
- if (key in options && typeof (value = options[key]) !== "boolean") {
35
- throw new TypeError(`Expected the "${key}" option to be a boolean`);
36
- }
37
- return value;
38
- };
39
- exports.cppdb = Symbol();
40
- exports.inspect = Symbol.for("nodejs.util.inspect.custom");
41
- });
42
-
43
- // node_modules/better-sqlite3/lib/sqlite-error.js
44
- var require_sqlite_error = __commonJS((exports, module) => {
45
- var descriptor = { value: "SqliteError", writable: true, enumerable: false, configurable: true };
46
- function SqliteError(message, code) {
47
- if (new.target !== SqliteError) {
48
- return new SqliteError(message, code);
49
- }
50
- if (typeof code !== "string") {
51
- throw new TypeError("Expected second argument to be a string");
52
- }
53
- Error.call(this, message);
54
- descriptor.value = "" + message;
55
- Object.defineProperty(this, "message", descriptor);
56
- Error.captureStackTrace(this, SqliteError);
57
- this.code = code;
58
- }
59
- Object.setPrototypeOf(SqliteError, Error);
60
- Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
61
- Object.defineProperty(SqliteError.prototype, "name", descriptor);
62
- module.exports = SqliteError;
63
- });
64
-
65
- // node_modules/file-uri-to-path/index.js
66
- var require_file_uri_to_path = __commonJS((exports, module) => {
67
- var sep = __require("path").sep || "/";
68
- module.exports = fileUriToPath;
69
- function fileUriToPath(uri) {
70
- if (typeof uri != "string" || uri.length <= 7 || uri.substring(0, 7) != "file://") {
71
- throw new TypeError("must pass in a file:// URI to convert to a file path");
72
- }
73
- var rest = decodeURI(uri.substring(7));
74
- var firstSlash = rest.indexOf("/");
75
- var host = rest.substring(0, firstSlash);
76
- var path = rest.substring(firstSlash + 1);
77
- if (host == "localhost")
78
- host = "";
79
- if (host) {
80
- host = sep + sep + host;
81
- }
82
- path = path.replace(/^(.+)\|/, "$1:");
83
- if (sep == "\\") {
84
- path = path.replace(/\//g, "\\");
85
- }
86
- if (/^.+\:/.test(path)) {} else {
87
- path = sep + path;
88
- }
89
- return host + path;
90
- }
91
- });
92
-
93
- // node_modules/bindings/bindings.js
94
- var require_bindings = __commonJS((exports, module) => {
95
- var __filename = "/Users/hasna/Workspace/hasna/opensource/opensourcedev/open-brains/node_modules/bindings/bindings.js";
96
- var fs = __require("fs");
97
- var path = __require("path");
98
- var fileURLToPath = require_file_uri_to_path();
99
- var join = path.join;
100
- var dirname = path.dirname;
101
- var exists2 = fs.accessSync && function(path2) {
102
- try {
103
- fs.accessSync(path2);
104
- } catch (e) {
105
- return false;
106
- }
107
- return true;
108
- } || fs.existsSync || path.existsSync;
109
- var defaults = {
110
- arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
111
- compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
112
- platform: process.platform,
113
- arch: process.arch,
114
- nodePreGyp: "node-v" + process.versions.modules + "-" + process.platform + "-" + process.arch,
115
- version: process.versions.node,
116
- bindings: "bindings.node",
117
- try: [
118
- ["module_root", "build", "bindings"],
119
- ["module_root", "build", "Debug", "bindings"],
120
- ["module_root", "build", "Release", "bindings"],
121
- ["module_root", "out", "Debug", "bindings"],
122
- ["module_root", "Debug", "bindings"],
123
- ["module_root", "out", "Release", "bindings"],
124
- ["module_root", "Release", "bindings"],
125
- ["module_root", "build", "default", "bindings"],
126
- ["module_root", "compiled", "version", "platform", "arch", "bindings"],
127
- ["module_root", "addon-build", "release", "install-root", "bindings"],
128
- ["module_root", "addon-build", "debug", "install-root", "bindings"],
129
- ["module_root", "addon-build", "default", "install-root", "bindings"],
130
- ["module_root", "lib", "binding", "nodePreGyp", "bindings"]
131
- ]
132
- };
133
- function bindings(opts) {
134
- if (typeof opts == "string") {
135
- opts = { bindings: opts };
136
- } else if (!opts) {
137
- opts = {};
138
- }
139
- Object.keys(defaults).map(function(i2) {
140
- if (!(i2 in opts))
141
- opts[i2] = defaults[i2];
142
- });
143
- if (!opts.module_root) {
144
- opts.module_root = exports.getRoot(exports.getFileName());
145
- }
146
- if (path.extname(opts.bindings) != ".node") {
147
- opts.bindings += ".node";
148
- }
149
- var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
150
- var tries = [], i = 0, l = opts.try.length, n, b, err;
151
- for (;i < l; i++) {
152
- n = join.apply(null, opts.try[i].map(function(p) {
153
- return opts[p] || p;
154
- }));
155
- tries.push(n);
156
- try {
157
- b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
158
- if (!opts.path) {
159
- b.path = n;
160
- }
161
- return b;
162
- } catch (e) {
163
- if (e.code !== "MODULE_NOT_FOUND" && e.code !== "QUALIFIED_PATH_RESOLUTION_FAILED" && !/not find/i.test(e.message)) {
164
- throw e;
165
- }
166
- }
167
- }
168
- err = new Error(`Could not locate the bindings file. Tried:
169
- ` + tries.map(function(a) {
170
- return opts.arrow + a;
171
- }).join(`
172
- `));
173
- err.tries = tries;
174
- throw err;
175
- }
176
- module.exports = exports = bindings;
177
- exports.getFileName = function getFileName(calling_file) {
178
- var { prepareStackTrace: origPST, stackTraceLimit: origSTL } = Error, dummy = {}, fileName;
179
- Error.stackTraceLimit = 10;
180
- Error.prepareStackTrace = function(e, st) {
181
- for (var i = 0, l = st.length;i < l; i++) {
182
- fileName = st[i].getFileName();
183
- if (fileName !== __filename) {
184
- if (calling_file) {
185
- if (fileName !== calling_file) {
186
- return;
187
- }
188
- } else {
189
- return;
190
- }
191
- }
192
- }
193
- };
194
- Error.captureStackTrace(dummy);
195
- dummy.stack;
196
- Error.prepareStackTrace = origPST;
197
- Error.stackTraceLimit = origSTL;
198
- var fileSchema = "file://";
199
- if (fileName.indexOf(fileSchema) === 0) {
200
- fileName = fileURLToPath(fileName);
201
- }
202
- return fileName;
203
- };
204
- exports.getRoot = function getRoot(file) {
205
- var dir = dirname(file), prev;
206
- while (true) {
207
- if (dir === ".") {
208
- dir = process.cwd();
209
- }
210
- if (exists2(join(dir, "package.json")) || exists2(join(dir, "node_modules"))) {
211
- return dir;
212
- }
213
- if (prev === dir) {
214
- throw new Error('Could not find module root given file: "' + file + '". Do you have a `package.json` file? ');
215
- }
216
- prev = dir;
217
- dir = join(dir, "..");
218
- }
219
- };
220
- });
221
-
222
- // node_modules/better-sqlite3/lib/methods/wrappers.js
223
- var require_wrappers = __commonJS((exports) => {
224
- var { cppdb } = require_util();
225
- exports.prepare = function prepare(sql2) {
226
- return this[cppdb].prepare(sql2, this, false);
227
- };
228
- exports.exec = function exec(sql2) {
229
- this[cppdb].exec(sql2);
230
- return this;
231
- };
232
- exports.close = function close() {
233
- this[cppdb].close();
234
- return this;
235
- };
236
- exports.loadExtension = function loadExtension(...args) {
237
- this[cppdb].loadExtension(...args);
238
- return this;
239
- };
240
- exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
241
- this[cppdb].defaultSafeIntegers(...args);
242
- return this;
243
- };
244
- exports.unsafeMode = function unsafeMode(...args) {
245
- this[cppdb].unsafeMode(...args);
246
- return this;
247
- };
248
- exports.getters = {
249
- name: {
250
- get: function name() {
251
- return this[cppdb].name;
252
- },
253
- enumerable: true
254
- },
255
- open: {
256
- get: function open() {
257
- return this[cppdb].open;
258
- },
259
- enumerable: true
260
- },
261
- inTransaction: {
262
- get: function inTransaction() {
263
- return this[cppdb].inTransaction;
264
- },
265
- enumerable: true
266
- },
267
- readonly: {
268
- get: function readonly() {
269
- return this[cppdb].readonly;
270
- },
271
- enumerable: true
272
- },
273
- memory: {
274
- get: function memory() {
275
- return this[cppdb].memory;
276
- },
277
- enumerable: true
278
- }
279
- };
280
- });
281
-
282
- // node_modules/better-sqlite3/lib/methods/transaction.js
283
- var require_transaction = __commonJS((exports, module) => {
284
- var { cppdb } = require_util();
285
- var controllers = new WeakMap;
286
- module.exports = function transaction(fn) {
287
- if (typeof fn !== "function")
288
- throw new TypeError("Expected first argument to be a function");
289
- const db = this[cppdb];
290
- const controller = getController(db, this);
291
- const { apply } = Function.prototype;
292
- const properties = {
293
- default: { value: wrapTransaction(apply, fn, db, controller.default) },
294
- deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
295
- immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
296
- exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
297
- database: { value: this, enumerable: true }
298
- };
299
- Object.defineProperties(properties.default.value, properties);
300
- Object.defineProperties(properties.deferred.value, properties);
301
- Object.defineProperties(properties.immediate.value, properties);
302
- Object.defineProperties(properties.exclusive.value, properties);
303
- return properties.default.value;
304
- };
305
- var getController = (db, self) => {
306
- let controller = controllers.get(db);
307
- if (!controller) {
308
- const shared = {
309
- commit: db.prepare("COMMIT", self, false),
310
- rollback: db.prepare("ROLLBACK", self, false),
311
- savepoint: db.prepare("SAVEPOINT `\t_bs3.\t`", self, false),
312
- release: db.prepare("RELEASE `\t_bs3.\t`", self, false),
313
- rollbackTo: db.prepare("ROLLBACK TO `\t_bs3.\t`", self, false)
314
- };
315
- controllers.set(db, controller = {
316
- default: Object.assign({ begin: db.prepare("BEGIN", self, false) }, shared),
317
- deferred: Object.assign({ begin: db.prepare("BEGIN DEFERRED", self, false) }, shared),
318
- immediate: Object.assign({ begin: db.prepare("BEGIN IMMEDIATE", self, false) }, shared),
319
- exclusive: Object.assign({ begin: db.prepare("BEGIN EXCLUSIVE", self, false) }, shared)
320
- });
321
- }
322
- return controller;
323
- };
324
- var wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
325
- let before, after, undo;
326
- if (db.inTransaction) {
327
- before = savepoint;
328
- after = release;
329
- undo = rollbackTo;
330
- } else {
331
- before = begin;
332
- after = commit;
333
- undo = rollback;
334
- }
335
- before.run();
336
- try {
337
- const result = apply.call(fn, this, arguments);
338
- if (result && typeof result.then === "function") {
339
- throw new TypeError("Transaction function cannot return a promise");
340
- }
341
- after.run();
342
- return result;
343
- } catch (ex) {
344
- if (db.inTransaction) {
345
- undo.run();
346
- if (undo !== rollback)
347
- after.run();
348
- }
349
- throw ex;
350
- }
351
- };
352
- });
353
-
354
- // node_modules/better-sqlite3/lib/methods/pragma.js
355
- var require_pragma = __commonJS((exports, module) => {
356
- var { getBooleanOption, cppdb } = require_util();
357
- module.exports = function pragma(source, options) {
358
- if (options == null)
359
- options = {};
360
- if (typeof source !== "string")
361
- throw new TypeError("Expected first argument to be a string");
362
- if (typeof options !== "object")
363
- throw new TypeError("Expected second argument to be an options object");
364
- const simple = getBooleanOption(options, "simple");
365
- const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
366
- return simple ? stmt.pluck().get() : stmt.all();
367
- };
368
- });
369
-
370
- // node_modules/better-sqlite3/lib/methods/backup.js
371
- var require_backup = __commonJS((exports, module) => {
372
- var fs = __require("fs");
373
- var path = __require("path");
374
- var { promisify } = __require("util");
375
- var { cppdb } = require_util();
376
- var fsAccess = promisify(fs.access);
377
- module.exports = async function backup(filename, options) {
378
- if (options == null)
379
- options = {};
380
- if (typeof filename !== "string")
381
- throw new TypeError("Expected first argument to be a string");
382
- if (typeof options !== "object")
383
- throw new TypeError("Expected second argument to be an options object");
384
- filename = filename.trim();
385
- const attachedName = "attached" in options ? options.attached : "main";
386
- const handler = "progress" in options ? options.progress : null;
387
- if (!filename)
388
- throw new TypeError("Backup filename cannot be an empty string");
389
- if (filename === ":memory:")
390
- throw new TypeError('Invalid backup filename ":memory:"');
391
- if (typeof attachedName !== "string")
392
- throw new TypeError('Expected the "attached" option to be a string');
393
- if (!attachedName)
394
- throw new TypeError('The "attached" option cannot be an empty string');
395
- if (handler != null && typeof handler !== "function")
396
- throw new TypeError('Expected the "progress" option to be a function');
397
- await fsAccess(path.dirname(filename)).catch(() => {
398
- throw new TypeError("Cannot save backup because the directory does not exist");
399
- });
400
- const isNewFile = await fsAccess(filename).then(() => false, () => true);
401
- return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
402
- };
403
- var runBackup = (backup, handler) => {
404
- let rate = 0;
405
- let useDefault = true;
406
- return new Promise((resolve, reject) => {
407
- setImmediate(function step() {
408
- try {
409
- const progress = backup.transfer(rate);
410
- if (!progress.remainingPages) {
411
- backup.close();
412
- resolve(progress);
413
- return;
414
- }
415
- if (useDefault) {
416
- useDefault = false;
417
- rate = 100;
418
- }
419
- if (handler) {
420
- const ret = handler(progress);
421
- if (ret !== undefined) {
422
- if (typeof ret === "number" && ret === ret)
423
- rate = Math.max(0, Math.min(2147483647, Math.round(ret)));
424
- else
425
- throw new TypeError("Expected progress callback to return a number or undefined");
426
- }
427
- }
428
- setImmediate(step);
429
- } catch (err) {
430
- backup.close();
431
- reject(err);
432
- }
433
- });
434
- });
435
- };
436
- });
437
-
438
- // node_modules/better-sqlite3/lib/methods/serialize.js
439
- var require_serialize = __commonJS((exports, module) => {
440
- var { cppdb } = require_util();
441
- module.exports = function serialize(options) {
442
- if (options == null)
443
- options = {};
444
- if (typeof options !== "object")
445
- throw new TypeError("Expected first argument to be an options object");
446
- const attachedName = "attached" in options ? options.attached : "main";
447
- if (typeof attachedName !== "string")
448
- throw new TypeError('Expected the "attached" option to be a string');
449
- if (!attachedName)
450
- throw new TypeError('The "attached" option cannot be an empty string');
451
- return this[cppdb].serialize(attachedName);
452
- };
453
- });
454
-
455
- // node_modules/better-sqlite3/lib/methods/function.js
456
- var require_function = __commonJS((exports, module) => {
457
- var { getBooleanOption, cppdb } = require_util();
458
- module.exports = function defineFunction(name, options, fn) {
459
- if (options == null)
460
- options = {};
461
- if (typeof options === "function") {
462
- fn = options;
463
- options = {};
464
- }
465
- if (typeof name !== "string")
466
- throw new TypeError("Expected first argument to be a string");
467
- if (typeof fn !== "function")
468
- throw new TypeError("Expected last argument to be a function");
469
- if (typeof options !== "object")
470
- throw new TypeError("Expected second argument to be an options object");
471
- if (!name)
472
- throw new TypeError("User-defined function name cannot be an empty string");
473
- const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
474
- const deterministic = getBooleanOption(options, "deterministic");
475
- const directOnly = getBooleanOption(options, "directOnly");
476
- const varargs = getBooleanOption(options, "varargs");
477
- let argCount = -1;
478
- if (!varargs) {
479
- argCount = fn.length;
480
- if (!Number.isInteger(argCount) || argCount < 0)
481
- throw new TypeError("Expected function.length to be a positive integer");
482
- if (argCount > 100)
483
- throw new RangeError("User-defined functions cannot have more than 100 arguments");
484
- }
485
- this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
486
- return this;
487
- };
488
- });
489
-
490
- // node_modules/better-sqlite3/lib/methods/aggregate.js
491
- var require_aggregate = __commonJS((exports, module) => {
492
- var { getBooleanOption, cppdb } = require_util();
493
- module.exports = function defineAggregate(name, options) {
494
- if (typeof name !== "string")
495
- throw new TypeError("Expected first argument to be a string");
496
- if (typeof options !== "object" || options === null)
497
- throw new TypeError("Expected second argument to be an options object");
498
- if (!name)
499
- throw new TypeError("User-defined function name cannot be an empty string");
500
- const start = "start" in options ? options.start : null;
501
- const step = getFunctionOption(options, "step", true);
502
- const inverse = getFunctionOption(options, "inverse", false);
503
- const result = getFunctionOption(options, "result", false);
504
- const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
505
- const deterministic = getBooleanOption(options, "deterministic");
506
- const directOnly = getBooleanOption(options, "directOnly");
507
- const varargs = getBooleanOption(options, "varargs");
508
- let argCount = -1;
509
- if (!varargs) {
510
- argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
511
- if (argCount > 0)
512
- argCount -= 1;
513
- if (argCount > 100)
514
- throw new RangeError("User-defined functions cannot have more than 100 arguments");
515
- }
516
- this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
517
- return this;
518
- };
519
- var getFunctionOption = (options, key, required) => {
520
- const value = key in options ? options[key] : null;
521
- if (typeof value === "function")
522
- return value;
523
- if (value != null)
524
- throw new TypeError(`Expected the "${key}" option to be a function`);
525
- if (required)
526
- throw new TypeError(`Missing required option "${key}"`);
527
- return null;
528
- };
529
- var getLength = ({ length }) => {
530
- if (Number.isInteger(length) && length >= 0)
531
- return length;
532
- throw new TypeError("Expected function.length to be a positive integer");
533
- };
534
- });
535
-
536
- // node_modules/better-sqlite3/lib/methods/table.js
537
- var require_table = __commonJS((exports, module) => {
538
- var { cppdb } = require_util();
539
- module.exports = function defineTable(name, factory) {
540
- if (typeof name !== "string")
541
- throw new TypeError("Expected first argument to be a string");
542
- if (!name)
543
- throw new TypeError("Virtual table module name cannot be an empty string");
544
- let eponymous = false;
545
- if (typeof factory === "object" && factory !== null) {
546
- eponymous = true;
547
- factory = defer(parseTableDefinition(factory, "used", name));
548
- } else {
549
- if (typeof factory !== "function")
550
- throw new TypeError("Expected second argument to be a function or a table definition object");
551
- factory = wrapFactory(factory);
552
- }
553
- this[cppdb].table(factory, name, eponymous);
554
- return this;
555
- };
556
- function wrapFactory(factory) {
557
- return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
558
- const thisObject = {
559
- module: moduleName,
560
- database: databaseName,
561
- table: tableName
562
- };
563
- const def = apply.call(factory, thisObject, args);
564
- if (typeof def !== "object" || def === null) {
565
- throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
566
- }
567
- return parseTableDefinition(def, "returned", moduleName);
568
- };
569
- }
570
- function parseTableDefinition(def, verb, moduleName) {
571
- if (!hasOwnProperty.call(def, "rows")) {
572
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
573
- }
574
- if (!hasOwnProperty.call(def, "columns")) {
575
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
576
- }
577
- const rows = def.rows;
578
- if (typeof rows !== "function" || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
579
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
580
- }
581
- let columns = def.columns;
582
- if (!Array.isArray(columns) || !(columns = [...columns]).every((x) => typeof x === "string")) {
583
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
584
- }
585
- if (columns.length !== new Set(columns).size) {
586
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
587
- }
588
- if (!columns.length) {
589
- throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
590
- }
591
- let parameters;
592
- if (hasOwnProperty.call(def, "parameters")) {
593
- parameters = def.parameters;
594
- if (!Array.isArray(parameters) || !(parameters = [...parameters]).every((x) => typeof x === "string")) {
595
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
596
- }
597
- } else {
598
- parameters = inferParameters(rows);
599
- }
600
- if (parameters.length !== new Set(parameters).size) {
601
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
602
- }
603
- if (parameters.length > 32) {
604
- throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
605
- }
606
- for (const parameter of parameters) {
607
- if (columns.includes(parameter)) {
608
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
609
- }
610
- }
611
- let safeIntegers = 2;
612
- if (hasOwnProperty.call(def, "safeIntegers")) {
613
- const bool = def.safeIntegers;
614
- if (typeof bool !== "boolean") {
615
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
616
- }
617
- safeIntegers = +bool;
618
- }
619
- let directOnly = false;
620
- if (hasOwnProperty.call(def, "directOnly")) {
621
- directOnly = def.directOnly;
622
- if (typeof directOnly !== "boolean") {
623
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
624
- }
625
- }
626
- const columnDefinitions = [
627
- ...parameters.map(identifier).map((str) => `${str} HIDDEN`),
628
- ...columns.map(identifier)
629
- ];
630
- return [
631
- `CREATE TABLE x(${columnDefinitions.join(", ")});`,
632
- wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),
633
- parameters,
634
- safeIntegers,
635
- directOnly
636
- ];
637
- }
638
- function wrapGenerator(generator, columnMap, moduleName) {
639
- return function* virtualTable(...args) {
640
- const output = args.map((x) => Buffer.isBuffer(x) ? Buffer.from(x) : x);
641
- for (let i = 0;i < columnMap.size; ++i) {
642
- output.push(null);
643
- }
644
- for (const row of generator(...args)) {
645
- if (Array.isArray(row)) {
646
- extractRowArray(row, output, columnMap.size, moduleName);
647
- yield output;
648
- } else if (typeof row === "object" && row !== null) {
649
- extractRowObject(row, output, columnMap, moduleName);
650
- yield output;
651
- } else {
652
- throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
653
- }
654
- }
655
- };
656
- }
657
- function extractRowArray(row, output, columnCount, moduleName) {
658
- if (row.length !== columnCount) {
659
- throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
660
- }
661
- const offset = output.length - columnCount;
662
- for (let i = 0;i < columnCount; ++i) {
663
- output[i + offset] = row[i];
664
- }
665
- }
666
- function extractRowObject(row, output, columnMap, moduleName) {
667
- let count = 0;
668
- for (const key of Object.keys(row)) {
669
- const index = columnMap.get(key);
670
- if (index === undefined) {
671
- throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
672
- }
673
- output[index] = row[key];
674
- count += 1;
675
- }
676
- if (count !== columnMap.size) {
677
- throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
678
- }
679
- }
680
- function inferParameters({ length }) {
681
- if (!Number.isInteger(length) || length < 0) {
682
- throw new TypeError("Expected function.length to be a positive integer");
683
- }
684
- const params = [];
685
- for (let i = 0;i < length; ++i) {
686
- params.push(`$${i + 1}`);
687
- }
688
- return params;
689
- }
690
- var { hasOwnProperty } = Object.prototype;
691
- var { apply } = Function.prototype;
692
- var GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {});
693
- var identifier = (str) => `"${str.replace(/"/g, '""')}"`;
694
- var defer = (x) => () => x;
695
- });
696
-
697
- // node_modules/better-sqlite3/lib/methods/inspect.js
698
- var require_inspect = __commonJS((exports, module) => {
699
- var DatabaseInspection = function Database() {};
700
- module.exports = function inspect(depth, opts) {
701
- return Object.assign(new DatabaseInspection, this);
702
- };
703
- });
704
-
705
- // node_modules/better-sqlite3/lib/database.js
706
- var require_database = __commonJS((exports, module) => {
707
- var fs = __require("fs");
708
- var path = __require("path");
709
- var util = require_util();
710
- var SqliteError = require_sqlite_error();
711
- var DEFAULT_ADDON;
712
- function Database(filenameGiven, options) {
713
- if (new.target == null) {
714
- return new Database(filenameGiven, options);
715
- }
716
- let buffer;
717
- if (Buffer.isBuffer(filenameGiven)) {
718
- buffer = filenameGiven;
719
- filenameGiven = ":memory:";
720
- }
721
- if (filenameGiven == null)
722
- filenameGiven = "";
723
- if (options == null)
724
- options = {};
725
- if (typeof filenameGiven !== "string")
726
- throw new TypeError("Expected first argument to be a string");
727
- if (typeof options !== "object")
728
- throw new TypeError("Expected second argument to be an options object");
729
- if ("readOnly" in options)
730
- throw new TypeError('Misspelled option "readOnly" should be "readonly"');
731
- if ("memory" in options)
732
- throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
733
- const filename = filenameGiven.trim();
734
- const anonymous = filename === "" || filename === ":memory:";
735
- const readonly = util.getBooleanOption(options, "readonly");
736
- const fileMustExist = util.getBooleanOption(options, "fileMustExist");
737
- const timeout = "timeout" in options ? options.timeout : 5000;
738
- const verbose = "verbose" in options ? options.verbose : null;
739
- const nativeBinding = "nativeBinding" in options ? options.nativeBinding : null;
740
- if (readonly && anonymous && !buffer)
741
- throw new TypeError("In-memory/temporary databases cannot be readonly");
742
- if (!Number.isInteger(timeout) || timeout < 0)
743
- throw new TypeError('Expected the "timeout" option to be a positive integer');
744
- if (timeout > 2147483647)
745
- throw new RangeError('Option "timeout" cannot be greater than 2147483647');
746
- if (verbose != null && typeof verbose !== "function")
747
- throw new TypeError('Expected the "verbose" option to be a function');
748
- if (nativeBinding != null && typeof nativeBinding !== "string" && typeof nativeBinding !== "object")
749
- throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
750
- let addon;
751
- if (nativeBinding == null) {
752
- addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
753
- } else if (typeof nativeBinding === "string") {
754
- const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
755
- addon = requireFunc(path.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
756
- } else {
757
- addon = nativeBinding;
758
- }
759
- if (!addon.isInitialized) {
760
- addon.setErrorConstructor(SqliteError);
761
- addon.isInitialized = true;
762
- }
763
- if (!anonymous && !fs.existsSync(path.dirname(filename))) {
764
- throw new TypeError("Cannot open database because the directory does not exist");
765
- }
766
- Object.defineProperties(this, {
767
- [util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
768
- ...wrappers.getters
769
- });
770
- }
771
- var wrappers = require_wrappers();
772
- Database.prototype.prepare = wrappers.prepare;
773
- Database.prototype.transaction = require_transaction();
774
- Database.prototype.pragma = require_pragma();
775
- Database.prototype.backup = require_backup();
776
- Database.prototype.serialize = require_serialize();
777
- Database.prototype.function = require_function();
778
- Database.prototype.aggregate = require_aggregate();
779
- Database.prototype.table = require_table();
780
- Database.prototype.loadExtension = wrappers.loadExtension;
781
- Database.prototype.exec = wrappers.exec;
782
- Database.prototype.close = wrappers.close;
783
- Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
784
- Database.prototype.unsafeMode = wrappers.unsafeMode;
785
- Database.prototype[util.inspect] = require_inspect();
786
- module.exports = Database;
787
- });
788
-
789
- // node_modules/better-sqlite3/lib/index.js
790
- var require_lib = __commonJS((exports, module) => {
791
- module.exports = require_database();
792
- module.exports.SqliteError = require_sqlite_error();
793
- });
794
-
795
29
  // src/mcp/index.ts
796
30
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
797
31
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -799,8 +33,8 @@ import {
799
33
  CallToolRequestSchema,
800
34
  ListToolsRequestSchema
801
35
  } from "@modelcontextprotocol/sdk/types.js";
802
- import { readFileSync as readFileSync2, existsSync } from "fs";
803
- import { resolve } from "path";
36
+ import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
37
+ import { resolve as resolve2 } from "path";
804
38
  import { homedir as homedir3 } from "os";
805
39
 
806
40
  // node_modules/drizzle-orm/entity.js
@@ -2159,8 +1393,8 @@ function mapRelationalRow(tablesConfig, tableConfig, row, buildQueryResultSelect
2159
1393
  return result;
2160
1394
  }
2161
1395
 
2162
- // node_modules/drizzle-orm/better-sqlite3/driver.js
2163
- var import_better_sqlite3 = __toESM(require_lib(), 1);
1396
+ // node_modules/drizzle-orm/bun-sqlite/driver.js
1397
+ import { Database } from "bun:sqlite";
2164
1398
 
2165
1399
  // node_modules/drizzle-orm/selection-proxy.js
2166
1400
  class SelectionProxyHandler {
@@ -4288,32 +3522,39 @@ class SQLiteTransaction extends BaseSQLiteDatabase {
4288
3522
  }
4289
3523
  }
4290
3524
 
4291
- // node_modules/drizzle-orm/better-sqlite3/session.js
4292
- class BetterSQLiteSession extends SQLiteSession {
3525
+ // node_modules/drizzle-orm/bun-sqlite/session.js
3526
+ class SQLiteBunSession extends SQLiteSession {
4293
3527
  constructor(client, dialect, schema, options = {}) {
4294
3528
  super(dialect);
4295
3529
  this.client = client;
4296
3530
  this.schema = schema;
4297
3531
  this.logger = options.logger ?? new NoopLogger;
4298
3532
  }
4299
- static [entityKind] = "BetterSQLiteSession";
3533
+ static [entityKind] = "SQLiteBunSession";
4300
3534
  logger;
3535
+ exec(query) {
3536
+ this.client.exec(query);
3537
+ }
4301
3538
  prepareQuery(query, fields, executeMethod, isResponseInArrayMode, customResultMapper) {
4302
3539
  const stmt = this.client.prepare(query.sql);
4303
3540
  return new PreparedQuery(stmt, query, this.logger, fields, executeMethod, isResponseInArrayMode, customResultMapper);
4304
3541
  }
4305
3542
  transaction(transaction, config = {}) {
4306
- const tx = new BetterSQLiteTransaction("sync", this.dialect, this, this.schema);
4307
- const nativeTx = this.client.transaction(transaction);
4308
- return nativeTx[config.behavior ?? "deferred"](tx);
3543
+ const tx = new SQLiteBunTransaction("sync", this.dialect, this, this.schema);
3544
+ let result;
3545
+ const nativeTx = this.client.transaction(() => {
3546
+ result = transaction(tx);
3547
+ });
3548
+ nativeTx[config.behavior ?? "deferred"]();
3549
+ return result;
4309
3550
  }
4310
3551
  }
4311
3552
 
4312
- class BetterSQLiteTransaction extends SQLiteTransaction {
4313
- static [entityKind] = "BetterSQLiteTransaction";
3553
+ class SQLiteBunTransaction extends SQLiteTransaction {
3554
+ static [entityKind] = "SQLiteBunTransaction";
4314
3555
  transaction(transaction) {
4315
3556
  const savepointName = `sp${this.nestedIndex}`;
4316
- const tx = new BetterSQLiteTransaction("sync", this.dialect, this.session, this.schema, this.nestedIndex + 1);
3557
+ const tx = new SQLiteBunTransaction("sync", this.dialect, this.session, this.schema, this.nestedIndex + 1);
4317
3558
  this.session.run(sql.raw(`savepoint ${savepointName}`));
4318
3559
  try {
4319
3560
  const result = transaction(tx);
@@ -4335,14 +3576,14 @@ class PreparedQuery extends SQLitePreparedQuery {
4335
3576
  this._isResponseInArrayMode = _isResponseInArrayMode;
4336
3577
  this.customResultMapper = customResultMapper;
4337
3578
  }
4338
- static [entityKind] = "BetterSQLitePreparedQuery";
3579
+ static [entityKind] = "SQLiteBunPreparedQuery";
4339
3580
  run(placeholderValues) {
4340
3581
  const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
4341
3582
  this.logger.logQuery(this.query.sql, params);
4342
3583
  return this.stmt.run(...params);
4343
3584
  }
4344
3585
  all(placeholderValues) {
4345
- const { fields, joinsNotNullableMap, query, logger, stmt, customResultMapper } = this;
3586
+ const { fields, query, logger, joinsNotNullableMap, stmt, customResultMapper } = this;
4346
3587
  if (!fields && !customResultMapper) {
4347
3588
  const params = fillPlaceholders(query.params, placeholderValues ?? {});
4348
3589
  logger.logQuery(query.sql, params);
@@ -4357,14 +3598,14 @@ class PreparedQuery extends SQLitePreparedQuery {
4357
3598
  get(placeholderValues) {
4358
3599
  const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
4359
3600
  this.logger.logQuery(this.query.sql, params);
4360
- const { fields, stmt, joinsNotNullableMap, customResultMapper } = this;
4361
- if (!fields && !customResultMapper) {
4362
- return stmt.get(...params);
4363
- }
4364
- const row = stmt.raw().get(...params);
3601
+ const row = this.stmt.values(...params)[0];
4365
3602
  if (!row) {
4366
3603
  return;
4367
3604
  }
3605
+ const { fields, joinsNotNullableMap, customResultMapper } = this;
3606
+ if (!fields && !customResultMapper) {
3607
+ return row;
3608
+ }
4368
3609
  if (customResultMapper) {
4369
3610
  return customResultMapper([row]);
4370
3611
  }
@@ -4373,16 +3614,16 @@ class PreparedQuery extends SQLitePreparedQuery {
4373
3614
  values(placeholderValues) {
4374
3615
  const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
4375
3616
  this.logger.logQuery(this.query.sql, params);
4376
- return this.stmt.raw().all(...params);
3617
+ return this.stmt.values(...params);
4377
3618
  }
4378
3619
  isResponseInArrayMode() {
4379
3620
  return this._isResponseInArrayMode;
4380
3621
  }
4381
3622
  }
4382
3623
 
4383
- // node_modules/drizzle-orm/better-sqlite3/driver.js
4384
- class BetterSQLite3Database extends BaseSQLiteDatabase {
4385
- static [entityKind] = "BetterSQLite3Database";
3624
+ // node_modules/drizzle-orm/bun-sqlite/driver.js
3625
+ class BunSQLiteDatabase extends BaseSQLiteDatabase {
3626
+ static [entityKind] = "BunSQLiteDatabase";
4386
3627
  }
4387
3628
  function construct(client, config = {}) {
4388
3629
  const dialect = new SQLiteSyncDialect({ casing: config.casing });
@@ -4401,14 +3642,14 @@ function construct(client, config = {}) {
4401
3642
  tableNamesMap: tablesConfig.tableNamesMap
4402
3643
  };
4403
3644
  }
4404
- const session = new BetterSQLiteSession(client, dialect, schema, { logger });
4405
- const db = new BetterSQLite3Database("sync", dialect, session, schema);
3645
+ const session = new SQLiteBunSession(client, dialect, schema, { logger });
3646
+ const db = new BunSQLiteDatabase("sync", dialect, session, schema);
4406
3647
  db.$client = client;
4407
3648
  return db;
4408
3649
  }
4409
3650
  function drizzle(...params) {
4410
3651
  if (params[0] === undefined || typeof params[0] === "string") {
4411
- const instance = params[0] === undefined ? new import_better_sqlite3.default : new import_better_sqlite3.default(params[0]);
3652
+ const instance = params[0] === undefined ? new Database : new Database(params[0]);
4412
3653
  return construct(instance, params[1]);
4413
3654
  }
4414
3655
  if (isConfig(params[0])) {
@@ -4416,11 +3657,12 @@ function drizzle(...params) {
4416
3657
  if (client)
4417
3658
  return construct(client, drizzleConfig);
4418
3659
  if (typeof connection === "object") {
4419
- const { source, ...options } = connection;
4420
- const instance2 = new import_better_sqlite3.default(source, options);
3660
+ const { source, ...opts } = connection;
3661
+ const options = Object.values(opts).filter((v) => v !== undefined).length ? opts : undefined;
3662
+ const instance2 = new Database(source, options);
4421
3663
  return construct(instance2, drizzleConfig);
4422
3664
  }
4423
- const instance = new import_better_sqlite3.default(connection);
3665
+ const instance = new Database(connection);
4424
3666
  return construct(instance, drizzleConfig);
4425
3667
  }
4426
3668
  return construct(params[0], params[1]);
@@ -4433,7 +3675,7 @@ function drizzle(...params) {
4433
3675
  })(drizzle || (drizzle = {}));
4434
3676
 
4435
3677
  // src/db/index.ts
4436
- var import_better_sqlite33 = __toESM(require_lib(), 1);
3678
+ import { Database as Database2 } from "bun:sqlite";
4437
3679
  import { mkdirSync } from "fs";
4438
3680
  import { dirname, join } from "path";
4439
3681
  import { homedir } from "os";
@@ -4454,6 +3696,10 @@ var fineTunedModels = sqliteTable("fine_tuned_models", {
4454
3696
  enum: ["pending", "running", "succeeded", "failed", "cancelled"]
4455
3697
  }).notNull().default("pending"),
4456
3698
  fineTuneJobId: text("fine_tune_job_id"),
3699
+ displayName: text("display_name"),
3700
+ description: text("description"),
3701
+ collection: text("collection"),
3702
+ tags: text("tags"),
4457
3703
  createdAt: integer("created_at").notNull(),
4458
3704
  updatedAt: integer("updated_at").notNull()
4459
3705
  });
@@ -4492,6 +3738,10 @@ function createTables(sqlite) {
4492
3738
  provider TEXT NOT NULL,
4493
3739
  status TEXT NOT NULL DEFAULT 'pending',
4494
3740
  fine_tune_job_id TEXT,
3741
+ display_name TEXT,
3742
+ description TEXT,
3743
+ collection TEXT,
3744
+ tags TEXT,
4495
3745
  created_at INTEGER NOT NULL,
4496
3746
  updated_at INTEGER NOT NULL
4497
3747
  );
@@ -4520,9 +3770,9 @@ function createTables(sqlite) {
4520
3770
  function getDb(dbPath) {
4521
3771
  const resolvedPath = dbPath ?? DEFAULT_DB_PATH;
4522
3772
  ensureDir(resolvedPath);
4523
- const sqlite = new import_better_sqlite33.default(resolvedPath);
4524
- sqlite.pragma("journal_mode = WAL");
4525
- sqlite.pragma("foreign_keys = ON");
3773
+ const sqlite = new Database2(resolvedPath);
3774
+ sqlite.run("PRAGMA journal_mode = WAL");
3775
+ sqlite.run("PRAGMA foreign_keys = ON");
4526
3776
  createTables(sqlite);
4527
3777
  return drizzle(sqlite, { schema: exports_schema });
4528
3778
  }
@@ -10185,7 +9435,7 @@ class ThinkerLabsProvider {
10185
9435
  }
10186
9436
 
10187
9437
  // src/lib/gatherers/todos.ts
10188
- var import_better_sqlite34 = __toESM(require_lib(), 1);
9438
+ import { Database as Database3 } from "bun:sqlite";
10189
9439
  import { homedir as homedir2 } from "os";
10190
9440
  import { join as join2 } from "path";
10191
9441
  var SYSTEM_PROMPT = "You are a task management assistant that helps users create, update, search, and manage tasks and projects.";
@@ -10239,7 +9489,7 @@ ${matched.map((t) => `- [${t.short_id ?? t.id}] ${t.title} (${t.status})`).join(
10239
9489
  }
10240
9490
  async function gatherFromTodos(options = {}) {
10241
9491
  const dbPath = join2(homedir2(), ".todos", "todos.db");
10242
- const db = new import_better_sqlite34.default(dbPath, { readonly: true });
9492
+ const db = new Database3(dbPath, { readonly: true, create: false });
10243
9493
  try {
10244
9494
  let query = "SELECT * FROM tasks WHERE 1=1";
10245
9495
  const params = [];
@@ -10252,7 +9502,7 @@ async function gatherFromTodos(options = {}) {
10252
9502
  query += " LIMIT ?";
10253
9503
  params.push(options.limit * 2);
10254
9504
  }
10255
- const tasks = db.prepare(query).all(...params);
9505
+ const tasks = db.query(query).all(...params);
10256
9506
  const examples = [];
10257
9507
  for (const task of tasks) {
10258
9508
  examples.push(taskToCreateExample(task));
@@ -10275,6 +9525,33 @@ async function gatherFromTodos(options = {}) {
10275
9525
  }
10276
9526
  }
10277
9527
 
9528
+ // src/lib/package-metadata.ts
9529
+ import { existsSync, readFileSync as readFileSync2 } from "fs";
9530
+ import { dirname as dirname2, resolve } from "path";
9531
+ import { fileURLToPath } from "url";
9532
+ var DEFAULT_VERSION = "0.0.0";
9533
+ var cachedVersion;
9534
+ function getPackageJsonPath() {
9535
+ return resolve(dirname2(fileURLToPath(import.meta.url)), "../../package.json");
9536
+ }
9537
+ function getPackageVersion() {
9538
+ if (cachedVersion) {
9539
+ return cachedVersion;
9540
+ }
9541
+ const packageJsonPath = getPackageJsonPath();
9542
+ if (!existsSync(packageJsonPath)) {
9543
+ cachedVersion = DEFAULT_VERSION;
9544
+ return cachedVersion;
9545
+ }
9546
+ try {
9547
+ const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
9548
+ cachedVersion = typeof packageJson.version === "string" ? packageJson.version : DEFAULT_VERSION;
9549
+ } catch {
9550
+ cachedVersion = DEFAULT_VERSION;
9551
+ }
9552
+ return cachedVersion;
9553
+ }
9554
+
10278
9555
  // src/mcp/index.ts
10279
9556
  function getProvider(provider) {
10280
9557
  if (provider === "openai")
@@ -10284,312 +9561,330 @@ function getProvider(provider) {
10284
9561
  throw new Error(`Unknown provider: ${provider}`);
10285
9562
  }
10286
9563
  function defaultOutputDir() {
10287
- return resolve(homedir3(), ".brains", "datasets");
10288
- }
10289
- var server = new Server({ name: "brains", version: "0.0.1" }, { capabilities: { tools: {} } });
10290
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
10291
- tools: [
10292
- {
10293
- name: "list_models",
10294
- description: "List all fine-tuned models tracked in the local DB",
10295
- inputSchema: {
10296
- type: "object",
10297
- properties: {},
10298
- required: []
10299
- }
10300
- },
10301
- {
10302
- name: "get_model",
10303
- description: "Get details for a specific fine-tuned model",
10304
- inputSchema: {
10305
- type: "object",
10306
- properties: {
10307
- model_id: { type: "string", description: "Model ID" }
10308
- },
10309
- required: ["model_id"]
10310
- }
10311
- },
10312
- {
10313
- name: "start_finetune",
10314
- description: "Upload a training file and start a fine-tuning job",
10315
- inputSchema: {
10316
- type: "object",
10317
- properties: {
10318
- provider: {
10319
- type: "string",
10320
- enum: ["openai", "thinker-labs"],
10321
- description: "Provider to use for fine-tuning"
9564
+ return resolve2(homedir3(), ".brains", "datasets");
9565
+ }
9566
+ var MCP_SERVER_INFO = {
9567
+ name: "brains",
9568
+ version: getPackageVersion()
9569
+ };
9570
+ function createMcpServer() {
9571
+ const server = new Server(MCP_SERVER_INFO, { capabilities: { tools: {} } });
9572
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
9573
+ tools: [
9574
+ {
9575
+ name: "list_models",
9576
+ description: "List all fine-tuned models tracked in the local DB",
9577
+ inputSchema: {
9578
+ type: "object",
9579
+ properties: {},
9580
+ required: []
9581
+ }
9582
+ },
9583
+ {
9584
+ name: "get_model",
9585
+ description: "Get details for a specific fine-tuned model",
9586
+ inputSchema: {
9587
+ type: "object",
9588
+ properties: {
9589
+ model_id: { type: "string", description: "Model ID" }
10322
9590
  },
10323
- base_model: {
10324
- type: "string",
10325
- description: "Base model identifier (e.g. gpt-4o-mini-2024-07-18)"
9591
+ required: ["model_id"]
9592
+ }
9593
+ },
9594
+ {
9595
+ name: "start_finetune",
9596
+ description: "Upload a training file and start a fine-tuning job",
9597
+ inputSchema: {
9598
+ type: "object",
9599
+ properties: {
9600
+ provider: {
9601
+ type: "string",
9602
+ enum: ["openai", "thinker-labs"],
9603
+ description: "Provider to use for fine-tuning"
9604
+ },
9605
+ base_model: {
9606
+ type: "string",
9607
+ description: "Base model identifier (e.g. gpt-4o-mini-2024-07-18)"
9608
+ },
9609
+ dataset_path: {
9610
+ type: "string",
9611
+ description: "Absolute path to the JSONL training file"
9612
+ },
9613
+ name: {
9614
+ type: "string",
9615
+ description: "Optional friendly name for this model"
9616
+ }
10326
9617
  },
10327
- dataset_path: {
10328
- type: "string",
10329
- description: "Absolute path to the JSONL training file"
9618
+ required: ["provider", "base_model", "dataset_path"]
9619
+ }
9620
+ },
9621
+ {
9622
+ name: "get_finetune_status",
9623
+ description: "Check the status of a fine-tuning job",
9624
+ inputSchema: {
9625
+ type: "object",
9626
+ properties: {
9627
+ job_id: { type: "string", description: "Fine-tune job ID" },
9628
+ provider: {
9629
+ type: "string",
9630
+ enum: ["openai", "thinker-labs"],
9631
+ description: "Provider that owns the job"
9632
+ }
10330
9633
  },
10331
- name: {
10332
- type: "string",
10333
- description: "Optional friendly name for this model"
10334
- }
10335
- },
10336
- required: ["provider", "base_model", "dataset_path"]
10337
- }
10338
- },
10339
- {
10340
- name: "get_finetune_status",
10341
- description: "Check the status of a fine-tuning job",
10342
- inputSchema: {
10343
- type: "object",
10344
- properties: {
10345
- job_id: { type: "string", description: "Fine-tune job ID" },
10346
- provider: {
10347
- type: "string",
10348
- enum: ["openai", "thinker-labs"],
10349
- description: "Provider that owns the job"
10350
- }
10351
- },
10352
- required: ["job_id", "provider"]
10353
- }
10354
- },
10355
- {
10356
- name: "gather_training_data",
10357
- description: "Gather training data from ecosystem sources (todos, mementos, conversations, sessions)",
10358
- inputSchema: {
10359
- type: "object",
10360
- properties: {
10361
- sources: {
10362
- type: "array",
10363
- items: { type: "string" },
10364
- description: "Sources to gather from: todos, mementos, conversations, sessions"
9634
+ required: ["job_id", "provider"]
9635
+ }
9636
+ },
9637
+ {
9638
+ name: "gather_training_data",
9639
+ description: "Gather training data from ecosystem sources (todos, mementos, conversations, sessions)",
9640
+ inputSchema: {
9641
+ type: "object",
9642
+ properties: {
9643
+ sources: {
9644
+ type: "array",
9645
+ items: { type: "string" },
9646
+ description: "Sources to gather from: todos, mementos, conversations, sessions"
9647
+ },
9648
+ limit: {
9649
+ type: "number",
9650
+ description: "Max examples per source (default: unlimited)"
9651
+ },
9652
+ output_dir: {
9653
+ type: "string",
9654
+ description: "Directory to write JSONL files (default: ~/.brains/datasets/)"
9655
+ }
10365
9656
  },
10366
- limit: {
10367
- type: "number",
10368
- description: "Max examples per source (default: unlimited)"
9657
+ required: ["sources"]
9658
+ }
9659
+ },
9660
+ {
9661
+ name: "preview_training_data",
9662
+ description: "Preview examples from a JSONL training file",
9663
+ inputSchema: {
9664
+ type: "object",
9665
+ properties: {
9666
+ file_path: {
9667
+ type: "string",
9668
+ description: "Absolute path to the JSONL file to preview"
9669
+ },
9670
+ limit: {
9671
+ type: "number",
9672
+ description: "Max number of examples to return (default: 5)"
9673
+ }
10369
9674
  },
10370
- output_dir: {
10371
- type: "string",
10372
- description: "Directory to write JSONL files (default: ~/.brains/datasets/)"
10373
- }
10374
- },
10375
- required: ["sources"]
9675
+ required: ["file_path"]
9676
+ }
10376
9677
  }
10377
- },
10378
- {
10379
- name: "preview_training_data",
10380
- description: "Preview examples from a JSONL training file",
10381
- inputSchema: {
10382
- type: "object",
10383
- properties: {
10384
- file_path: {
10385
- type: "string",
10386
- description: "Absolute path to the JSONL file to preview"
10387
- },
10388
- limit: {
10389
- type: "number",
10390
- description: "Max number of examples to return (default: 5)"
9678
+ ]
9679
+ }));
9680
+ server.setRequestHandler(CallToolRequestSchema, async (request2) => {
9681
+ const { name, arguments: args } = request2.params;
9682
+ try {
9683
+ switch (name) {
9684
+ case "list_models": {
9685
+ const db = getDb();
9686
+ const models = await db.select({
9687
+ id: fineTunedModels.id,
9688
+ name: fineTunedModels.name,
9689
+ provider: fineTunedModels.provider,
9690
+ status: fineTunedModels.status,
9691
+ base_model: fineTunedModels.baseModel,
9692
+ created_at: fineTunedModels.createdAt
9693
+ }).from(fineTunedModels).orderBy(fineTunedModels.createdAt);
9694
+ return {
9695
+ content: [
9696
+ {
9697
+ type: "text",
9698
+ text: JSON.stringify(models, null, 2)
9699
+ }
9700
+ ]
9701
+ };
9702
+ }
9703
+ case "get_model": {
9704
+ const { model_id } = args;
9705
+ const db = getDb();
9706
+ const results = await db.select().from(fineTunedModels).where(eq(fineTunedModels.id, model_id));
9707
+ if (results.length === 0) {
9708
+ return {
9709
+ content: [{ type: "text", text: `Model not found: ${model_id}` }],
9710
+ isError: true
9711
+ };
10391
9712
  }
10392
- },
10393
- required: ["file_path"]
10394
- }
10395
- }
10396
- ]
10397
- }));
10398
- server.setRequestHandler(CallToolRequestSchema, async (request2) => {
10399
- const { name, arguments: args } = request2.params;
10400
- try {
10401
- switch (name) {
10402
- case "list_models": {
10403
- const db = getDb();
10404
- const models = await db.select({
10405
- id: fineTunedModels.id,
10406
- name: fineTunedModels.name,
10407
- provider: fineTunedModels.provider,
10408
- status: fineTunedModels.status,
10409
- base_model: fineTunedModels.baseModel,
10410
- created_at: fineTunedModels.createdAt
10411
- }).from(fineTunedModels).orderBy(fineTunedModels.createdAt);
10412
- return {
10413
- content: [
10414
- {
10415
- type: "text",
10416
- text: JSON.stringify(models, null, 2)
10417
- }
10418
- ]
10419
- };
10420
- }
10421
- case "get_model": {
10422
- const { model_id } = args;
10423
- const db = getDb();
10424
- const results = await db.select().from(fineTunedModels).where(eq(fineTunedModels.id, model_id));
10425
- if (results.length === 0) {
10426
9713
  return {
10427
- content: [{ type: "text", text: `Model not found: ${model_id}` }],
10428
- isError: true
9714
+ content: [
9715
+ { type: "text", text: JSON.stringify(results[0], null, 2) }
9716
+ ]
10429
9717
  };
10430
9718
  }
10431
- return {
10432
- content: [
10433
- { type: "text", text: JSON.stringify(results[0], null, 2) }
10434
- ]
10435
- };
10436
- }
10437
- case "start_finetune": {
10438
- const {
10439
- provider,
10440
- base_model,
10441
- dataset_path,
10442
- name: modelName
10443
- } = args;
10444
- const resolvedPath = resolve(dataset_path);
10445
- if (!existsSync(resolvedPath)) {
9719
+ case "start_finetune": {
9720
+ const {
9721
+ provider,
9722
+ base_model,
9723
+ dataset_path,
9724
+ name: modelName
9725
+ } = args;
9726
+ const resolvedPath = resolve2(dataset_path);
9727
+ if (!existsSync2(resolvedPath)) {
9728
+ return {
9729
+ content: [
9730
+ {
9731
+ type: "text",
9732
+ text: `Dataset file not found: ${resolvedPath}`
9733
+ }
9734
+ ],
9735
+ isError: true
9736
+ };
9737
+ }
9738
+ const p = getProvider(provider);
9739
+ const { fileId } = await p.uploadTrainingFile(resolvedPath);
9740
+ const { jobId, status } = await p.createFineTuneJob(fileId, base_model, modelName);
9741
+ const db = getDb();
9742
+ const now = Date.now();
9743
+ const id = `${provider}-${jobId}`;
9744
+ await db.insert(fineTunedModels).values({
9745
+ id,
9746
+ name: modelName ?? `${base_model}-finetune-${now}`,
9747
+ provider,
9748
+ baseModel: base_model,
9749
+ status: "pending",
9750
+ fineTuneJobId: jobId,
9751
+ createdAt: now,
9752
+ updatedAt: now
9753
+ });
10446
9754
  return {
10447
9755
  content: [
10448
9756
  {
10449
9757
  type: "text",
10450
- text: `Dataset file not found: ${resolvedPath}`
9758
+ text: JSON.stringify({ job_id: jobId, status, model_db_id: id }, null, 2)
10451
9759
  }
10452
- ],
10453
- isError: true
9760
+ ]
10454
9761
  };
10455
9762
  }
10456
- const p = getProvider(provider);
10457
- const { fileId } = await p.uploadTrainingFile(resolvedPath);
10458
- const { jobId, status } = await p.createFineTuneJob(fileId, base_model, modelName);
10459
- const db = getDb();
10460
- const now = Date.now();
10461
- const id = `${provider}-${jobId}`;
10462
- await db.insert(fineTunedModels).values({
10463
- id,
10464
- name: modelName ?? `${base_model}-finetune-${now}`,
10465
- provider,
10466
- baseModel: base_model,
10467
- status: "pending",
10468
- fineTuneJobId: jobId,
10469
- createdAt: now,
10470
- updatedAt: now
10471
- });
10472
- return {
10473
- content: [
10474
- {
10475
- type: "text",
10476
- text: JSON.stringify({ job_id: jobId, status, model_db_id: id }, null, 2)
10477
- }
10478
- ]
10479
- };
10480
- }
10481
- case "get_finetune_status": {
10482
- const { job_id, provider } = args;
10483
- const p = getProvider(provider);
10484
- const result = await p.getFineTuneStatus(job_id);
10485
- const db = getDb();
10486
- const dbId = `${provider}-${job_id}`;
10487
- const existing = await db.select().from(fineTunedModels).where(eq(fineTunedModels.id, dbId));
10488
- if (existing.length > 0) {
10489
- const mappedStatus = (() => {
10490
- if (result.status === "succeeded")
10491
- return "succeeded";
10492
- if (result.status === "failed")
10493
- return "failed";
10494
- if (result.status === "cancelled")
10495
- return "cancelled";
10496
- if (result.status === "running")
10497
- return "running";
10498
- return "pending";
10499
- })();
10500
- await db.update(fineTunedModels).set({
10501
- status: mappedStatus,
10502
- updatedAt: Date.now()
10503
- }).where(eq(fineTunedModels.id, dbId));
10504
- }
10505
- return {
10506
- content: [
10507
- {
10508
- type: "text",
10509
- text: JSON.stringify({
10510
- job_id: result.jobId,
10511
- status: result.status,
10512
- model_id: result.fineTunedModel,
10513
- error: result.error
10514
- }, null, 2)
10515
- }
10516
- ]
10517
- };
10518
- }
10519
- case "gather_training_data": {
10520
- const {
10521
- sources,
10522
- limit: limit2,
10523
- output_dir
10524
- } = args;
10525
- const { mkdirSync: mkdirSync2, writeFileSync } = await import("fs");
10526
- const { join: join3 } = await import("path");
10527
- const outDir = output_dir ?? defaultOutputDir();
10528
- mkdirSync2(outDir, { recursive: true });
10529
- const datasets = [];
10530
- let totalExamples = 0;
10531
- for (const source of sources) {
10532
- let examples = [];
10533
- if (source === "todos") {
10534
- const result = await gatherFromTodos({ limit: limit2 });
10535
- examples = result.examples;
10536
- } else {
10537
- examples = [];
9763
+ case "get_finetune_status": {
9764
+ const { job_id, provider } = args;
9765
+ const p = getProvider(provider);
9766
+ const result = await p.getFineTuneStatus(job_id);
9767
+ const db = getDb();
9768
+ const dbId = `${provider}-${job_id}`;
9769
+ const existing = await db.select().from(fineTunedModels).where(eq(fineTunedModels.id, dbId));
9770
+ if (existing.length > 0) {
9771
+ const mappedStatus = (() => {
9772
+ if (result.status === "succeeded")
9773
+ return "succeeded";
9774
+ if (result.status === "failed")
9775
+ return "failed";
9776
+ if (result.status === "cancelled")
9777
+ return "cancelled";
9778
+ if (result.status === "running")
9779
+ return "running";
9780
+ return "pending";
9781
+ })();
9782
+ await db.update(fineTunedModels).set({
9783
+ status: mappedStatus,
9784
+ updatedAt: Date.now()
9785
+ }).where(eq(fineTunedModels.id, dbId));
10538
9786
  }
10539
- const filePath = join3(outDir, `${source}-${Date.now()}.jsonl`);
10540
- const jsonl = examples.map((ex) => JSON.stringify(ex)).join(`
10541
- `);
10542
- writeFileSync(filePath, jsonl, "utf-8");
10543
- datasets.push({ source, count: examples.length, file_path: filePath });
10544
- totalExamples += examples.length;
9787
+ return {
9788
+ content: [
9789
+ {
9790
+ type: "text",
9791
+ text: JSON.stringify({
9792
+ job_id: result.jobId,
9793
+ status: result.status,
9794
+ model_id: result.fineTunedModel,
9795
+ error: result.error
9796
+ }, null, 2)
9797
+ }
9798
+ ]
9799
+ };
10545
9800
  }
10546
- return {
10547
- content: [
10548
- {
10549
- type: "text",
10550
- text: JSON.stringify({ datasets, total_examples: totalExamples }, null, 2)
9801
+ case "gather_training_data": {
9802
+ const {
9803
+ sources,
9804
+ limit: limit2,
9805
+ output_dir
9806
+ } = args;
9807
+ const { mkdirSync: mkdirSync2, writeFileSync } = await import("fs");
9808
+ const { join: join3 } = await import("path");
9809
+ const outDir = output_dir ?? defaultOutputDir();
9810
+ mkdirSync2(outDir, { recursive: true });
9811
+ const datasets = [];
9812
+ let totalExamples = 0;
9813
+ for (const source of sources) {
9814
+ let examples = [];
9815
+ if (source === "todos") {
9816
+ const result = await gatherFromTodos({ limit: limit2 });
9817
+ examples = result.examples;
9818
+ } else {
9819
+ examples = [];
10551
9820
  }
10552
- ]
10553
- };
10554
- }
10555
- case "preview_training_data": {
10556
- const { file_path, limit: limit2 = 5 } = args;
10557
- const resolvedPath = resolve(file_path);
10558
- if (!existsSync(resolvedPath)) {
9821
+ const filePath = join3(outDir, `${source}-${Date.now()}.jsonl`);
9822
+ const jsonl = examples.map((ex) => JSON.stringify(ex)).join(`
9823
+ `);
9824
+ writeFileSync(filePath, jsonl, "utf-8");
9825
+ datasets.push({ source, count: examples.length, file_path: filePath });
9826
+ totalExamples += examples.length;
9827
+ }
10559
9828
  return {
10560
9829
  content: [
10561
- { type: "text", text: `File not found: ${resolvedPath}` }
10562
- ],
10563
- isError: true
9830
+ {
9831
+ type: "text",
9832
+ text: JSON.stringify({ datasets, total_examples: totalExamples }, null, 2)
9833
+ }
9834
+ ]
10564
9835
  };
10565
9836
  }
10566
- const content = readFileSync2(resolvedPath, "utf-8");
10567
- const lines = content.split(`
9837
+ case "preview_training_data": {
9838
+ const { file_path, limit: limit2 = 5 } = args;
9839
+ const resolvedPath = resolve2(file_path);
9840
+ if (!existsSync2(resolvedPath)) {
9841
+ return {
9842
+ content: [
9843
+ { type: "text", text: `File not found: ${resolvedPath}` }
9844
+ ],
9845
+ isError: true
9846
+ };
9847
+ }
9848
+ const content = readFileSync3(resolvedPath, "utf-8");
9849
+ const lines = content.split(`
10568
9850
  `).map((l) => l.trim()).filter(Boolean);
10569
- const total = lines.length;
10570
- const examples = lines.slice(0, limit2).map((line) => JSON.parse(line));
10571
- return {
10572
- content: [
10573
- {
10574
- type: "text",
10575
- text: JSON.stringify({ examples, total }, null, 2)
10576
- }
10577
- ]
10578
- };
9851
+ const total = lines.length;
9852
+ const examples = lines.slice(0, limit2).map((line) => JSON.parse(line));
9853
+ return {
9854
+ content: [
9855
+ {
9856
+ type: "text",
9857
+ text: JSON.stringify({ examples, total }, null, 2)
9858
+ }
9859
+ ]
9860
+ };
9861
+ }
9862
+ default:
9863
+ return {
9864
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
9865
+ isError: true
9866
+ };
10579
9867
  }
10580
- default:
10581
- return {
10582
- content: [{ type: "text", text: `Unknown tool: ${name}` }],
10583
- isError: true
10584
- };
9868
+ } catch (err) {
9869
+ const message = err instanceof Error ? err.message : String(err);
9870
+ return {
9871
+ content: [{ type: "text", text: `Error: ${message}` }],
9872
+ isError: true
9873
+ };
10585
9874
  }
10586
- } catch (err) {
10587
- const message = err instanceof Error ? err.message : String(err);
10588
- return {
10589
- content: [{ type: "text", text: `Error: ${message}` }],
10590
- isError: true
10591
- };
10592
- }
10593
- });
10594
- var transport = new StdioServerTransport;
10595
- await server.connect(transport);
9875
+ });
9876
+ return server;
9877
+ }
9878
+ async function startMcpServer(transport = new StdioServerTransport) {
9879
+ const server = createMcpServer();
9880
+ await server.connect(transport);
9881
+ return server;
9882
+ }
9883
+ if (import.meta.main) {
9884
+ await startMcpServer();
9885
+ }
9886
+ export {
9887
+ startMcpServer,
9888
+ createMcpServer,
9889
+ MCP_SERVER_INFO
9890
+ };