@hasna/brains 0.0.19 → 0.0.20
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/collections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCzC,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/collections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCzC,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6DlE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmM3D"}
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmM3D;AAED,iBAAS,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
|
+
import { fineTunedModels } from "../../db/index.js";
|
|
3
|
+
type ModelRow = typeof fineTunedModels.$inferSelect;
|
|
4
|
+
type Provider = ModelRow["provider"];
|
|
5
|
+
type ModelStatus = ModelRow["status"];
|
|
6
|
+
interface ListModelsOptions {
|
|
7
|
+
json?: boolean;
|
|
8
|
+
provider?: string;
|
|
9
|
+
status?: string;
|
|
10
|
+
limit?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function parseListLimit(rawLimit: string | undefined): number | undefined;
|
|
13
|
+
declare function parseListFilters(opts: ListModelsOptions): {
|
|
14
|
+
provider?: Provider;
|
|
15
|
+
status?: ModelStatus;
|
|
16
|
+
limit?: number;
|
|
17
|
+
};
|
|
2
18
|
export declare function registerModelsCommands(program: Command): void;
|
|
19
|
+
export { parseListFilters, parseListLimit };
|
|
3
20
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAS,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAKzE,KAAK,QAAQ,GAAG,OAAO,eAAe,CAAC,YAAY,CAAC;AACpD,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;AACrC,KAAK,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAUtC,UAAU,iBAAiB;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOxE;AAED,iBAAS,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG;IAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiBhH;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmQ7D;AAED,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -23207,12 +23207,58 @@ class ThinkerLabsProvider {
|
|
|
23207
23207
|
}
|
|
23208
23208
|
|
|
23209
23209
|
// src/cli/commands/models.ts
|
|
23210
|
+
var VALID_STATUSES = new Set([
|
|
23211
|
+
"pending",
|
|
23212
|
+
"running",
|
|
23213
|
+
"succeeded",
|
|
23214
|
+
"failed",
|
|
23215
|
+
"cancelled"
|
|
23216
|
+
]);
|
|
23217
|
+
function parseListLimit(rawLimit) {
|
|
23218
|
+
if (!rawLimit)
|
|
23219
|
+
return;
|
|
23220
|
+
const parsed = Number(rawLimit);
|
|
23221
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
23222
|
+
throw new Error(`Invalid --limit value: ${rawLimit}. Use a positive integer.`);
|
|
23223
|
+
}
|
|
23224
|
+
return parsed;
|
|
23225
|
+
}
|
|
23226
|
+
function parseListFilters(opts) {
|
|
23227
|
+
const providerRaw = opts.provider?.trim();
|
|
23228
|
+
const statusRaw = opts.status?.trim();
|
|
23229
|
+
if (providerRaw && providerRaw !== "openai" && providerRaw !== "thinker-labs") {
|
|
23230
|
+
throw new Error(`Invalid --provider value: ${providerRaw}. Use openai or thinker-labs.`);
|
|
23231
|
+
}
|
|
23232
|
+
if (statusRaw && !VALID_STATUSES.has(statusRaw)) {
|
|
23233
|
+
throw new Error(`Invalid --status value: ${statusRaw}. Use one of: ${Array.from(VALID_STATUSES).join(", ")}.`);
|
|
23234
|
+
}
|
|
23235
|
+
const limit2 = parseListLimit(opts.limit);
|
|
23236
|
+
const provider = providerRaw;
|
|
23237
|
+
const status = statusRaw;
|
|
23238
|
+
return { provider, status, limit: limit2 };
|
|
23239
|
+
}
|
|
23210
23240
|
function registerModelsCommands(program2) {
|
|
23211
23241
|
const modelsCmd = program2.command("models").description("Manage tracked fine-tuned models");
|
|
23212
|
-
|
|
23242
|
+
const ensureModelExists = async (id) => {
|
|
23243
|
+
const db = getDb();
|
|
23244
|
+
const [model] = await db.select({ id: fineTunedModels.id }).from(fineTunedModels).where(eq(fineTunedModels.id, id));
|
|
23245
|
+
if (!model) {
|
|
23246
|
+
printError(`Model not found: ${id}`);
|
|
23247
|
+
process.exit(1);
|
|
23248
|
+
}
|
|
23249
|
+
return db;
|
|
23250
|
+
};
|
|
23251
|
+
modelsCmd.command("list").description("List all tracked fine-tuned models").option("--provider <provider>", "Filter by provider (openai|thinker-labs)").option("--status <status>", "Filter by status (pending|running|succeeded|failed|cancelled)").option("--limit <n>", "Maximum number of results").option("--json", "Output as JSON").action(async (opts) => {
|
|
23213
23252
|
try {
|
|
23214
23253
|
const db = getDb();
|
|
23215
|
-
const
|
|
23254
|
+
const filters = parseListFilters(opts);
|
|
23255
|
+
const whereClause = filters.provider && filters.status ? and(eq(fineTunedModels.provider, filters.provider), eq(fineTunedModels.status, filters.status)) : filters.provider ? eq(fineTunedModels.provider, filters.provider) : filters.status ? eq(fineTunedModels.status, filters.status) : undefined;
|
|
23256
|
+
const query = db.select().from(fineTunedModels).$dynamic();
|
|
23257
|
+
if (whereClause)
|
|
23258
|
+
query.where(whereClause);
|
|
23259
|
+
if (filters.limit)
|
|
23260
|
+
query.limit(filters.limit);
|
|
23261
|
+
const models = await query;
|
|
23216
23262
|
if (opts.json) {
|
|
23217
23263
|
printJson(models);
|
|
23218
23264
|
return;
|
|
@@ -23272,7 +23318,7 @@ function registerModelsCommands(program2) {
|
|
|
23272
23318
|
});
|
|
23273
23319
|
modelsCmd.command("rename <id> <displayName>").description("Set the display name of a model").action(async (id, displayName) => {
|
|
23274
23320
|
try {
|
|
23275
|
-
const db =
|
|
23321
|
+
const db = await ensureModelExists(id);
|
|
23276
23322
|
await db.update(fineTunedModels).set({ displayName, updatedAt: Date.now() }).where(eq(fineTunedModels.id, id));
|
|
23277
23323
|
printSuccess(`Display name set to "${displayName}"`);
|
|
23278
23324
|
} catch (err) {
|
|
@@ -23282,9 +23328,9 @@ function registerModelsCommands(program2) {
|
|
|
23282
23328
|
});
|
|
23283
23329
|
modelsCmd.command("describe <id> <description>").description("Set the description of a model").action(async (id, description) => {
|
|
23284
23330
|
try {
|
|
23285
|
-
const db =
|
|
23331
|
+
const db = await ensureModelExists(id);
|
|
23286
23332
|
await db.update(fineTunedModels).set({ description, updatedAt: Date.now() }).where(eq(fineTunedModels.id, id));
|
|
23287
|
-
printSuccess(
|
|
23333
|
+
printSuccess("Description updated.");
|
|
23288
23334
|
} catch (err) {
|
|
23289
23335
|
printError(err instanceof Error ? err.message : String(err));
|
|
23290
23336
|
process.exit(1);
|
|
@@ -23328,7 +23374,7 @@ function registerModelsCommands(program2) {
|
|
|
23328
23374
|
});
|
|
23329
23375
|
modelsCmd.command("collection <id> <collectionName>").description("Set the collection of a model").action(async (id, collectionName) => {
|
|
23330
23376
|
try {
|
|
23331
|
-
const db =
|
|
23377
|
+
const db = await ensureModelExists(id);
|
|
23332
23378
|
await db.update(fineTunedModels).set({ collection: collectionName, updatedAt: Date.now() }).where(eq(fineTunedModels.id, id));
|
|
23333
23379
|
printSuccess(`Collection set to "${collectionName}"`);
|
|
23334
23380
|
} catch (err) {
|
|
@@ -23371,7 +23417,7 @@ function registerModelsCommands(program2) {
|
|
|
23371
23417
|
status: result.status,
|
|
23372
23418
|
startedAt: now
|
|
23373
23419
|
});
|
|
23374
|
-
printSuccess(
|
|
23420
|
+
printSuccess("Model imported successfully.");
|
|
23375
23421
|
console.log();
|
|
23376
23422
|
console.log(` Local ID: ${modelId}`);
|
|
23377
23423
|
console.log(` Job ID: ${jobId}`);
|
|
@@ -23584,7 +23630,7 @@ function registerFinetuneCommands(program2) {
|
|
|
23584
23630
|
// src/cli/commands/data.ts
|
|
23585
23631
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
23586
23632
|
import { readFileSync as readFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
23587
|
-
import { join as join13 } from "path";
|
|
23633
|
+
import { dirname as dirname3, join as join13 } from "path";
|
|
23588
23634
|
import { homedir as homedir12 } from "os";
|
|
23589
23635
|
var DEFAULT_DATASETS_DIR = join13(homedir12(), ".hasna", "brains", "datasets");
|
|
23590
23636
|
function registerDataCommands(program2) {
|
|
@@ -23696,7 +23742,7 @@ function registerDataCommands(program2) {
|
|
|
23696
23742
|
process.exit(1);
|
|
23697
23743
|
}
|
|
23698
23744
|
}
|
|
23699
|
-
mkdirSync6(
|
|
23745
|
+
mkdirSync6(getMergeOutputDirectory(opts.output), { recursive: true });
|
|
23700
23746
|
const allExamples = [];
|
|
23701
23747
|
for (const f of files) {
|
|
23702
23748
|
const lines = readFileSync6(f, "utf8").split(`
|
|
@@ -23762,6 +23808,11 @@ function registerDataCommands(program2) {
|
|
|
23762
23808
|
}
|
|
23763
23809
|
});
|
|
23764
23810
|
}
|
|
23811
|
+
function getMergeOutputDirectory(outputPath) {
|
|
23812
|
+
if (!outputPath)
|
|
23813
|
+
return DEFAULT_DATASETS_DIR;
|
|
23814
|
+
return dirname3(outputPath);
|
|
23815
|
+
}
|
|
23765
23816
|
|
|
23766
23817
|
// src/cli/commands/collections.ts
|
|
23767
23818
|
async function listCollections(json = false) {
|
|
@@ -23777,7 +23828,7 @@ async function listCollections(json = false) {
|
|
|
23777
23828
|
return;
|
|
23778
23829
|
}
|
|
23779
23830
|
if (rows.length === 0) {
|
|
23780
|
-
printInfo("No collections found. Set a collection with 'brains models
|
|
23831
|
+
printInfo("No collections found. Set a collection with 'brains models collection <model-id> <name>'.");
|
|
23781
23832
|
return;
|
|
23782
23833
|
}
|
|
23783
23834
|
printTable(["Collection", "Model Count", "Models"], rows.map((r) => [r.collection ?? "(none)", String(r.count), r.names ?? ""]));
|
|
@@ -23794,14 +23845,22 @@ function registerCollectionsCommands(program2) {
|
|
|
23794
23845
|
collectionsCmd.command("list").description("List all collections with model counts").option("--json", "Output as JSON").action(async (opts) => {
|
|
23795
23846
|
await listCollections(opts.json);
|
|
23796
23847
|
});
|
|
23797
|
-
collectionsCmd.command("show <name>").description("List all models in a collection").action(async (name) => {
|
|
23848
|
+
collectionsCmd.command("show <name>").description("List all models in a collection").option("--json", "Output as JSON").action(async (name, opts) => {
|
|
23798
23849
|
try {
|
|
23799
23850
|
const db = getDb();
|
|
23800
23851
|
const models = await db.select().from(fineTunedModels).where(eq(fineTunedModels.collection, name));
|
|
23801
23852
|
if (models.length === 0) {
|
|
23853
|
+
if (opts.json) {
|
|
23854
|
+
printJson([]);
|
|
23855
|
+
return;
|
|
23856
|
+
}
|
|
23802
23857
|
printInfo(`No models found in collection '${name}'.`);
|
|
23803
23858
|
return;
|
|
23804
23859
|
}
|
|
23860
|
+
if (opts.json) {
|
|
23861
|
+
printJson(models);
|
|
23862
|
+
return;
|
|
23863
|
+
}
|
|
23805
23864
|
printTable(["ID", "Name", "Provider", "Status", "Base Model"], models.map((m) => [m.id, m.name, m.provider, printStatus(m.status), m.baseModel]));
|
|
23806
23865
|
} catch (err) {
|
|
23807
23866
|
printError(err instanceof Error ? err.message : String(err));
|
|
@@ -23993,12 +24052,12 @@ function registerCloudCommands2(program2) {
|
|
|
23993
24052
|
|
|
23994
24053
|
// src/lib/package-metadata.ts
|
|
23995
24054
|
import { existsSync as existsSync12, readFileSync as readFileSync7 } from "fs";
|
|
23996
|
-
import { dirname as
|
|
24055
|
+
import { dirname as dirname4, resolve as resolve2 } from "path";
|
|
23997
24056
|
import { fileURLToPath } from "url";
|
|
23998
24057
|
var DEFAULT_VERSION = "0.0.0";
|
|
23999
24058
|
var cachedVersion;
|
|
24000
24059
|
function getPackageJsonPath() {
|
|
24001
|
-
return resolve2(
|
|
24060
|
+
return resolve2(dirname4(fileURLToPath(import.meta.url)), "../../package.json");
|
|
24002
24061
|
}
|
|
24003
24062
|
function getPackageVersion() {
|
|
24004
24063
|
if (cachedVersion) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/brains",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "Fine-tuned model tracker and trainer — wraps OpenAI + Thinker Labs, gathers training data from todos/mementos/conversations/sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|