@dexto/agent-management 1.4.0 → 1.5.1
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/AgentFactory.cjs +1 -2
- package/dist/AgentFactory.d.ts +1 -1
- package/dist/AgentFactory.d.ts.map +1 -1
- package/dist/AgentFactory.js +1 -2
- package/dist/config/config-enrichment.cjs +50 -1
- package/dist/config/config-enrichment.d.ts +2 -2
- package/dist/config/config-enrichment.d.ts.map +1 -1
- package/dist/config/config-enrichment.js +51 -3
- package/dist/config/discover-prompts.cjs +13 -0
- package/dist/config/discover-prompts.d.ts +13 -0
- package/dist/config/discover-prompts.d.ts.map +1 -1
- package/dist/config/discover-prompts.js +12 -0
- package/dist/config/errors.cjs +2 -2
- package/dist/config/errors.js +2 -2
- package/dist/index.cjs +69 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -2
- package/dist/installation.cjs +0 -13
- package/dist/installation.d.ts +0 -2
- package/dist/installation.d.ts.map +1 -1
- package/dist/installation.js +0 -13
- package/dist/models/custom-models.cjs +46 -2
- package/dist/models/custom-models.d.ts +54 -6
- package/dist/models/custom-models.d.ts.map +1 -1
- package/dist/models/custom-models.js +45 -2
- package/dist/models/index.cjs +89 -0
- package/dist/models/index.d.ts +11 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +68 -0
- package/dist/models/path-resolver.cjs +154 -0
- package/dist/models/path-resolver.d.ts +77 -0
- package/dist/models/path-resolver.d.ts.map +1 -0
- package/dist/models/path-resolver.js +108 -0
- package/dist/models/state-manager.cjs +220 -0
- package/dist/models/state-manager.d.ts +138 -0
- package/dist/models/state-manager.d.ts.map +1 -0
- package/dist/models/state-manager.js +184 -0
- package/dist/preferences/error-codes.cjs +2 -0
- package/dist/preferences/error-codes.d.ts +3 -1
- package/dist/preferences/error-codes.d.ts.map +1 -1
- package/dist/preferences/error-codes.js +2 -0
- package/dist/preferences/index.d.ts +1 -1
- package/dist/preferences/index.d.ts.map +1 -1
- package/dist/preferences/loader.cjs +35 -6
- package/dist/preferences/loader.d.ts +25 -4
- package/dist/preferences/loader.d.ts.map +1 -1
- package/dist/preferences/loader.js +35 -6
- package/dist/preferences/schemas.cjs +24 -3
- package/dist/preferences/schemas.d.ts +64 -24
- package/dist/preferences/schemas.d.ts.map +1 -1
- package/dist/preferences/schemas.js +31 -4
- package/dist/registry/registry.cjs +7 -43
- package/dist/registry/registry.d.ts +3 -6
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +7 -43
- package/dist/registry/types.d.ts +2 -4
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/resolver.cjs +20 -20
- package/dist/resolver.d.ts +1 -2
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +20 -20
- package/dist/utils/api-key-resolver.cjs +19 -1
- package/dist/utils/api-key-resolver.d.ts.map +1 -1
- package/dist/utils/api-key-resolver.js +19 -1
- package/dist/utils/api-key-store.cjs +46 -0
- package/dist/utils/api-key-store.d.ts +27 -0
- package/dist/utils/api-key-store.d.ts.map +1 -1
- package/dist/utils/api-key-store.js +44 -0
- package/dist/utils/env-file.cjs +20 -68
- package/dist/utils/env-file.d.ts +2 -1
- package/dist/utils/env-file.d.ts.map +1 -1
- package/dist/utils/env-file.js +20 -68
- package/dist/writer.cjs +20 -2
- package/dist/writer.d.ts +1 -0
- package/dist/writer.d.ts.map +1 -1
- package/dist/writer.js +20 -2
- package/package.json +2 -2
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var path_resolver_exports = {};
|
|
30
|
+
__export(path_resolver_exports, {
|
|
31
|
+
deleteModelDirectory: () => deleteModelDirectory,
|
|
32
|
+
ensureModelDirectory: () => ensureModelDirectory,
|
|
33
|
+
ensureModelsDirectory: () => ensureModelsDirectory,
|
|
34
|
+
formatSize: () => formatSize,
|
|
35
|
+
getModelDirectory: () => getModelDirectory,
|
|
36
|
+
getModelFilePath: () => getModelFilePath,
|
|
37
|
+
getModelFileSize: () => getModelFileSize,
|
|
38
|
+
getModelStatePath: () => getModelStatePath,
|
|
39
|
+
getModelTempDirectory: () => getModelTempDirectory,
|
|
40
|
+
getModelsDirectory: () => getModelsDirectory,
|
|
41
|
+
getModelsDiskUsage: () => getModelsDiskUsage,
|
|
42
|
+
listModelDirectories: () => listModelDirectories,
|
|
43
|
+
modelFileExists: () => modelFileExists
|
|
44
|
+
});
|
|
45
|
+
module.exports = __toCommonJS(path_resolver_exports);
|
|
46
|
+
var path = __toESM(require("path"), 1);
|
|
47
|
+
var import_fs = require("fs");
|
|
48
|
+
var import_os = require("os");
|
|
49
|
+
function getModelsDirectory() {
|
|
50
|
+
return path.join((0, import_os.homedir)(), ".dexto", "models");
|
|
51
|
+
}
|
|
52
|
+
function getModelFilePath(modelId, filename) {
|
|
53
|
+
return path.join(getModelsDirectory(), modelId, filename);
|
|
54
|
+
}
|
|
55
|
+
function getModelDirectory(modelId) {
|
|
56
|
+
return path.join(getModelsDirectory(), modelId);
|
|
57
|
+
}
|
|
58
|
+
function getModelStatePath() {
|
|
59
|
+
return path.join(getModelsDirectory(), "state.json");
|
|
60
|
+
}
|
|
61
|
+
function getModelTempDirectory() {
|
|
62
|
+
return path.join(getModelsDirectory(), ".tmp");
|
|
63
|
+
}
|
|
64
|
+
async function ensureModelsDirectory() {
|
|
65
|
+
const modelsDir = getModelsDirectory();
|
|
66
|
+
const tempDir = getModelTempDirectory();
|
|
67
|
+
await import_fs.promises.mkdir(modelsDir, { recursive: true });
|
|
68
|
+
await import_fs.promises.mkdir(tempDir, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
async function ensureModelDirectory(modelId) {
|
|
71
|
+
const modelDir = getModelDirectory(modelId);
|
|
72
|
+
await import_fs.promises.mkdir(modelDir, { recursive: true });
|
|
73
|
+
return modelDir;
|
|
74
|
+
}
|
|
75
|
+
async function modelFileExists(modelId, filename) {
|
|
76
|
+
const filePath = getModelFilePath(modelId, filename);
|
|
77
|
+
try {
|
|
78
|
+
await import_fs.promises.access(filePath);
|
|
79
|
+
return true;
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function getModelFileSize(modelId, filename) {
|
|
85
|
+
const filePath = getModelFilePath(modelId, filename);
|
|
86
|
+
try {
|
|
87
|
+
const stats = await import_fs.promises.stat(filePath);
|
|
88
|
+
return stats.size;
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function deleteModelDirectory(modelId) {
|
|
94
|
+
const modelDir = getModelDirectory(modelId);
|
|
95
|
+
try {
|
|
96
|
+
await import_fs.promises.rm(modelDir, { recursive: true, force: true });
|
|
97
|
+
return true;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function listModelDirectories() {
|
|
103
|
+
const modelsDir = getModelsDirectory();
|
|
104
|
+
try {
|
|
105
|
+
const entries = await import_fs.promises.readdir(modelsDir, { withFileTypes: true });
|
|
106
|
+
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
107
|
+
} catch {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function getModelsDiskUsage() {
|
|
112
|
+
const modelsDir = getModelsDirectory();
|
|
113
|
+
async function getDirSize(dir) {
|
|
114
|
+
let size = 0;
|
|
115
|
+
try {
|
|
116
|
+
const entries = await import_fs.promises.readdir(dir, { withFileTypes: true });
|
|
117
|
+
for (const entry of entries) {
|
|
118
|
+
const entryPath = path.join(dir, entry.name);
|
|
119
|
+
if (entry.isDirectory()) {
|
|
120
|
+
size += await getDirSize(entryPath);
|
|
121
|
+
} else if (entry.isFile()) {
|
|
122
|
+
const stats = await import_fs.promises.stat(entryPath);
|
|
123
|
+
size += stats.size;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} catch {
|
|
127
|
+
}
|
|
128
|
+
return size;
|
|
129
|
+
}
|
|
130
|
+
return getDirSize(modelsDir);
|
|
131
|
+
}
|
|
132
|
+
function formatSize(bytes) {
|
|
133
|
+
if (bytes === 0) return "0 B";
|
|
134
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
135
|
+
const k = 1024;
|
|
136
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
137
|
+
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${units[i]}`;
|
|
138
|
+
}
|
|
139
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
140
|
+
0 && (module.exports = {
|
|
141
|
+
deleteModelDirectory,
|
|
142
|
+
ensureModelDirectory,
|
|
143
|
+
ensureModelsDirectory,
|
|
144
|
+
formatSize,
|
|
145
|
+
getModelDirectory,
|
|
146
|
+
getModelFilePath,
|
|
147
|
+
getModelFileSize,
|
|
148
|
+
getModelStatePath,
|
|
149
|
+
getModelTempDirectory,
|
|
150
|
+
getModelsDirectory,
|
|
151
|
+
getModelsDiskUsage,
|
|
152
|
+
listModelDirectories,
|
|
153
|
+
modelFileExists
|
|
154
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path resolver for local model storage.
|
|
3
|
+
*
|
|
4
|
+
* Models are stored globally at ~/.dexto/models/ to be shared across projects.
|
|
5
|
+
* This avoids duplicating large model files for each project.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Get the base models directory path.
|
|
9
|
+
* Always returns global path: ~/.dexto/models/
|
|
10
|
+
*/
|
|
11
|
+
export declare function getModelsDirectory(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Get the path to a specific model file.
|
|
14
|
+
* @param modelId Model ID from registry
|
|
15
|
+
* @param filename GGUF filename
|
|
16
|
+
*/
|
|
17
|
+
export declare function getModelFilePath(modelId: string, filename: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get the path to a model's directory.
|
|
20
|
+
* @param modelId Model ID from registry
|
|
21
|
+
*/
|
|
22
|
+
export declare function getModelDirectory(modelId: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Get the path to the model state file.
|
|
25
|
+
* Stores download status, hashes, and usage metadata.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getModelStatePath(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Get the path to the model download temp directory.
|
|
30
|
+
* Used for in-progress downloads.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getModelTempDirectory(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Ensure the models directory and subdirectories exist.
|
|
35
|
+
*/
|
|
36
|
+
export declare function ensureModelsDirectory(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Ensure a specific model's directory exists.
|
|
39
|
+
* @param modelId Model ID from registry
|
|
40
|
+
*/
|
|
41
|
+
export declare function ensureModelDirectory(modelId: string): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Check if a model file exists at the expected path.
|
|
44
|
+
* @param modelId Model ID from registry
|
|
45
|
+
* @param filename GGUF filename
|
|
46
|
+
*/
|
|
47
|
+
export declare function modelFileExists(modelId: string, filename: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Get file size of an installed model.
|
|
50
|
+
* @param modelId Model ID from registry
|
|
51
|
+
* @param filename GGUF filename
|
|
52
|
+
* @returns File size in bytes, or null if file doesn't exist
|
|
53
|
+
*/
|
|
54
|
+
export declare function getModelFileSize(modelId: string, filename: string): Promise<number | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Delete a model's directory and all its files.
|
|
57
|
+
* @param modelId Model ID to delete
|
|
58
|
+
* @returns True if deleted, false if not found
|
|
59
|
+
*/
|
|
60
|
+
export declare function deleteModelDirectory(modelId: string): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* List all model directories in the models folder.
|
|
63
|
+
* @returns Array of model IDs (directory names)
|
|
64
|
+
*/
|
|
65
|
+
export declare function listModelDirectories(): Promise<string[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Get disk usage statistics for the models directory.
|
|
68
|
+
* @returns Total bytes used by models, or 0 if directory doesn't exist
|
|
69
|
+
*/
|
|
70
|
+
export declare function getModelsDiskUsage(): Promise<number>;
|
|
71
|
+
/**
|
|
72
|
+
* Format bytes to human-readable string.
|
|
73
|
+
* @param bytes Number of bytes
|
|
74
|
+
* @returns Formatted string (e.g., "4.5 GB")
|
|
75
|
+
*/
|
|
76
|
+
export declare function formatSize(bytes: number): string;
|
|
77
|
+
//# sourceMappingURL=path-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-resolver.d.ts","sourceRoot":"","sources":["../../src/models/path-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM3D;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI3E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQzF;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQhG;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ5E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ9D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAuB1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhD"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
function getModelsDirectory() {
|
|
5
|
+
return path.join(homedir(), ".dexto", "models");
|
|
6
|
+
}
|
|
7
|
+
function getModelFilePath(modelId, filename) {
|
|
8
|
+
return path.join(getModelsDirectory(), modelId, filename);
|
|
9
|
+
}
|
|
10
|
+
function getModelDirectory(modelId) {
|
|
11
|
+
return path.join(getModelsDirectory(), modelId);
|
|
12
|
+
}
|
|
13
|
+
function getModelStatePath() {
|
|
14
|
+
return path.join(getModelsDirectory(), "state.json");
|
|
15
|
+
}
|
|
16
|
+
function getModelTempDirectory() {
|
|
17
|
+
return path.join(getModelsDirectory(), ".tmp");
|
|
18
|
+
}
|
|
19
|
+
async function ensureModelsDirectory() {
|
|
20
|
+
const modelsDir = getModelsDirectory();
|
|
21
|
+
const tempDir = getModelTempDirectory();
|
|
22
|
+
await fs.mkdir(modelsDir, { recursive: true });
|
|
23
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
async function ensureModelDirectory(modelId) {
|
|
26
|
+
const modelDir = getModelDirectory(modelId);
|
|
27
|
+
await fs.mkdir(modelDir, { recursive: true });
|
|
28
|
+
return modelDir;
|
|
29
|
+
}
|
|
30
|
+
async function modelFileExists(modelId, filename) {
|
|
31
|
+
const filePath = getModelFilePath(modelId, filename);
|
|
32
|
+
try {
|
|
33
|
+
await fs.access(filePath);
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function getModelFileSize(modelId, filename) {
|
|
40
|
+
const filePath = getModelFilePath(modelId, filename);
|
|
41
|
+
try {
|
|
42
|
+
const stats = await fs.stat(filePath);
|
|
43
|
+
return stats.size;
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function deleteModelDirectory(modelId) {
|
|
49
|
+
const modelDir = getModelDirectory(modelId);
|
|
50
|
+
try {
|
|
51
|
+
await fs.rm(modelDir, { recursive: true, force: true });
|
|
52
|
+
return true;
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function listModelDirectories() {
|
|
58
|
+
const modelsDir = getModelsDirectory();
|
|
59
|
+
try {
|
|
60
|
+
const entries = await fs.readdir(modelsDir, { withFileTypes: true });
|
|
61
|
+
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
62
|
+
} catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function getModelsDiskUsage() {
|
|
67
|
+
const modelsDir = getModelsDirectory();
|
|
68
|
+
async function getDirSize(dir) {
|
|
69
|
+
let size = 0;
|
|
70
|
+
try {
|
|
71
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
const entryPath = path.join(dir, entry.name);
|
|
74
|
+
if (entry.isDirectory()) {
|
|
75
|
+
size += await getDirSize(entryPath);
|
|
76
|
+
} else if (entry.isFile()) {
|
|
77
|
+
const stats = await fs.stat(entryPath);
|
|
78
|
+
size += stats.size;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
}
|
|
83
|
+
return size;
|
|
84
|
+
}
|
|
85
|
+
return getDirSize(modelsDir);
|
|
86
|
+
}
|
|
87
|
+
function formatSize(bytes) {
|
|
88
|
+
if (bytes === 0) return "0 B";
|
|
89
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
90
|
+
const k = 1024;
|
|
91
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
92
|
+
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${units[i]}`;
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
deleteModelDirectory,
|
|
96
|
+
ensureModelDirectory,
|
|
97
|
+
ensureModelsDirectory,
|
|
98
|
+
formatSize,
|
|
99
|
+
getModelDirectory,
|
|
100
|
+
getModelFilePath,
|
|
101
|
+
getModelFileSize,
|
|
102
|
+
getModelStatePath,
|
|
103
|
+
getModelTempDirectory,
|
|
104
|
+
getModelsDirectory,
|
|
105
|
+
getModelsDiskUsage,
|
|
106
|
+
listModelDirectories,
|
|
107
|
+
modelFileExists
|
|
108
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var state_manager_exports = {};
|
|
20
|
+
__export(state_manager_exports, {
|
|
21
|
+
addInstalledModel: () => addInstalledModel,
|
|
22
|
+
addToDownloadQueue: () => addToDownloadQueue,
|
|
23
|
+
getActiveModel: () => getActiveModel,
|
|
24
|
+
getActiveModelId: () => getActiveModelId,
|
|
25
|
+
getAllInstalledModels: () => getAllInstalledModels,
|
|
26
|
+
getDownloadQueue: () => getDownloadQueue,
|
|
27
|
+
getInstalledModel: () => getInstalledModel,
|
|
28
|
+
getInstalledModelCount: () => getInstalledModelCount,
|
|
29
|
+
getTotalInstalledSize: () => getTotalInstalledSize,
|
|
30
|
+
isModelInstalled: () => isModelInstalled,
|
|
31
|
+
loadModelState: () => loadModelState,
|
|
32
|
+
registerManualModel: () => registerManualModel,
|
|
33
|
+
removeFromDownloadQueue: () => removeFromDownloadQueue,
|
|
34
|
+
removeInstalledModel: () => removeInstalledModel,
|
|
35
|
+
saveModelState: () => saveModelState,
|
|
36
|
+
setActiveModel: () => setActiveModel,
|
|
37
|
+
syncStateWithFilesystem: () => syncStateWithFilesystem,
|
|
38
|
+
updateModelLastUsed: () => updateModelLastUsed
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(state_manager_exports);
|
|
41
|
+
var import_fs = require("fs");
|
|
42
|
+
var import_path_resolver = require("./path-resolver.js");
|
|
43
|
+
const CURRENT_VERSION = "1.0";
|
|
44
|
+
function createDefaultState() {
|
|
45
|
+
return {
|
|
46
|
+
version: CURRENT_VERSION,
|
|
47
|
+
installed: {},
|
|
48
|
+
downloadQueue: []
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function loadModelState() {
|
|
52
|
+
const statePath = (0, import_path_resolver.getModelStatePath)();
|
|
53
|
+
try {
|
|
54
|
+
const content = await import_fs.promises.readFile(statePath, "utf-8");
|
|
55
|
+
const state = JSON.parse(content);
|
|
56
|
+
if (state.version !== CURRENT_VERSION) {
|
|
57
|
+
return migrateState(state);
|
|
58
|
+
}
|
|
59
|
+
return state;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error.code === "ENOENT") {
|
|
62
|
+
return createDefaultState();
|
|
63
|
+
}
|
|
64
|
+
console.warn("Invalid model state file, resetting to default");
|
|
65
|
+
return createDefaultState();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function saveModelState(state) {
|
|
69
|
+
await (0, import_path_resolver.ensureModelsDirectory)();
|
|
70
|
+
const statePath = (0, import_path_resolver.getModelStatePath)();
|
|
71
|
+
await import_fs.promises.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
72
|
+
}
|
|
73
|
+
function migrateState(state) {
|
|
74
|
+
return {
|
|
75
|
+
...state,
|
|
76
|
+
version: CURRENT_VERSION
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async function addInstalledModel(model) {
|
|
80
|
+
const state = await loadModelState();
|
|
81
|
+
state.installed[model.id] = model;
|
|
82
|
+
await saveModelState(state);
|
|
83
|
+
}
|
|
84
|
+
async function removeInstalledModel(modelId) {
|
|
85
|
+
const state = await loadModelState();
|
|
86
|
+
if (!state.installed[modelId]) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
delete state.installed[modelId];
|
|
90
|
+
if (state.activeModelId === modelId) {
|
|
91
|
+
delete state.activeModelId;
|
|
92
|
+
}
|
|
93
|
+
state.downloadQueue = state.downloadQueue.filter((id) => id !== modelId);
|
|
94
|
+
await saveModelState(state);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
async function getInstalledModel(modelId) {
|
|
98
|
+
const state = await loadModelState();
|
|
99
|
+
return state.installed[modelId] ?? null;
|
|
100
|
+
}
|
|
101
|
+
async function getAllInstalledModels() {
|
|
102
|
+
const state = await loadModelState();
|
|
103
|
+
return Object.values(state.installed);
|
|
104
|
+
}
|
|
105
|
+
async function isModelInstalled(modelId) {
|
|
106
|
+
const model = await getInstalledModel(modelId);
|
|
107
|
+
if (!model) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return (0, import_path_resolver.modelFileExists)(modelId, model.filename);
|
|
111
|
+
}
|
|
112
|
+
async function updateModelLastUsed(modelId) {
|
|
113
|
+
const state = await loadModelState();
|
|
114
|
+
const model = state.installed[modelId];
|
|
115
|
+
if (model) {
|
|
116
|
+
model.lastUsedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
117
|
+
await saveModelState(state);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function setActiveModel(modelId) {
|
|
121
|
+
const state = await loadModelState();
|
|
122
|
+
if (modelId === void 0) {
|
|
123
|
+
delete state.activeModelId;
|
|
124
|
+
} else {
|
|
125
|
+
state.activeModelId = modelId;
|
|
126
|
+
}
|
|
127
|
+
await saveModelState(state);
|
|
128
|
+
}
|
|
129
|
+
async function getActiveModelId() {
|
|
130
|
+
const state = await loadModelState();
|
|
131
|
+
return state.activeModelId;
|
|
132
|
+
}
|
|
133
|
+
async function getActiveModel() {
|
|
134
|
+
const activeId = await getActiveModelId();
|
|
135
|
+
if (!activeId) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return getInstalledModel(activeId);
|
|
139
|
+
}
|
|
140
|
+
async function addToDownloadQueue(modelId) {
|
|
141
|
+
const state = await loadModelState();
|
|
142
|
+
if (!state.downloadQueue.includes(modelId)) {
|
|
143
|
+
state.downloadQueue.push(modelId);
|
|
144
|
+
await saveModelState(state);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function removeFromDownloadQueue(modelId) {
|
|
148
|
+
const state = await loadModelState();
|
|
149
|
+
state.downloadQueue = state.downloadQueue.filter((id) => id !== modelId);
|
|
150
|
+
await saveModelState(state);
|
|
151
|
+
}
|
|
152
|
+
async function getDownloadQueue() {
|
|
153
|
+
const state = await loadModelState();
|
|
154
|
+
return [...state.downloadQueue];
|
|
155
|
+
}
|
|
156
|
+
async function syncStateWithFilesystem() {
|
|
157
|
+
const state = await loadModelState();
|
|
158
|
+
const removed = [];
|
|
159
|
+
const kept = [];
|
|
160
|
+
for (const [modelId, model] of Object.entries(state.installed)) {
|
|
161
|
+
const exists = await (0, import_path_resolver.modelFileExists)(modelId, model.filename);
|
|
162
|
+
if (exists) {
|
|
163
|
+
kept.push(modelId);
|
|
164
|
+
} else {
|
|
165
|
+
removed.push(modelId);
|
|
166
|
+
delete state.installed[modelId];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (state.activeModelId && removed.includes(state.activeModelId)) {
|
|
170
|
+
delete state.activeModelId;
|
|
171
|
+
}
|
|
172
|
+
if (removed.length > 0) {
|
|
173
|
+
await saveModelState(state);
|
|
174
|
+
}
|
|
175
|
+
return { removed, kept };
|
|
176
|
+
}
|
|
177
|
+
async function getTotalInstalledSize() {
|
|
178
|
+
const state = await loadModelState();
|
|
179
|
+
return Object.values(state.installed).reduce((total, model) => total + model.sizeBytes, 0);
|
|
180
|
+
}
|
|
181
|
+
async function getInstalledModelCount() {
|
|
182
|
+
const state = await loadModelState();
|
|
183
|
+
return Object.keys(state.installed).length;
|
|
184
|
+
}
|
|
185
|
+
async function registerManualModel(modelId, filename, sizeBytes, sha256) {
|
|
186
|
+
const filePath = (0, import_path_resolver.getModelFilePath)(modelId, filename);
|
|
187
|
+
const model = {
|
|
188
|
+
id: modelId,
|
|
189
|
+
filePath,
|
|
190
|
+
sizeBytes,
|
|
191
|
+
downloadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
192
|
+
source: "manual",
|
|
193
|
+
filename
|
|
194
|
+
};
|
|
195
|
+
if (sha256 !== void 0) {
|
|
196
|
+
model.sha256 = sha256;
|
|
197
|
+
}
|
|
198
|
+
await addInstalledModel(model);
|
|
199
|
+
}
|
|
200
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
201
|
+
0 && (module.exports = {
|
|
202
|
+
addInstalledModel,
|
|
203
|
+
addToDownloadQueue,
|
|
204
|
+
getActiveModel,
|
|
205
|
+
getActiveModelId,
|
|
206
|
+
getAllInstalledModels,
|
|
207
|
+
getDownloadQueue,
|
|
208
|
+
getInstalledModel,
|
|
209
|
+
getInstalledModelCount,
|
|
210
|
+
getTotalInstalledSize,
|
|
211
|
+
isModelInstalled,
|
|
212
|
+
loadModelState,
|
|
213
|
+
registerManualModel,
|
|
214
|
+
removeFromDownloadQueue,
|
|
215
|
+
removeInstalledModel,
|
|
216
|
+
saveModelState,
|
|
217
|
+
setActiveModel,
|
|
218
|
+
syncStateWithFilesystem,
|
|
219
|
+
updateModelLastUsed
|
|
220
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model state manager for tracking downloaded local models.
|
|
3
|
+
*
|
|
4
|
+
* Persists model metadata to ~/.dexto/models/state.json including:
|
|
5
|
+
* - Which models are installed
|
|
6
|
+
* - File paths and sizes
|
|
7
|
+
* - Download timestamps
|
|
8
|
+
* - Usage tracking
|
|
9
|
+
*
|
|
10
|
+
* Note: ModelSource and InstalledModel types here intentionally differ from
|
|
11
|
+
* packages/core/src/llm/providers/local/types.ts. This package extends the core
|
|
12
|
+
* types with agent-management specific needs:
|
|
13
|
+
* - ModelSource adds 'manual' for user-placed model files
|
|
14
|
+
* - InstalledModel adds 'filename' for file system operations (isModelInstalled, syncStateWithFilesystem)
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Source of the model download.
|
|
18
|
+
*/
|
|
19
|
+
export type ModelSource = 'huggingface' | 'manual';
|
|
20
|
+
/**
|
|
21
|
+
* Installed model metadata.
|
|
22
|
+
*/
|
|
23
|
+
export interface InstalledModel {
|
|
24
|
+
/** Model ID from registry */
|
|
25
|
+
id: string;
|
|
26
|
+
/** Absolute path to the .gguf file */
|
|
27
|
+
filePath: string;
|
|
28
|
+
/** File size in bytes */
|
|
29
|
+
sizeBytes: number;
|
|
30
|
+
/** When the model was downloaded (ISO timestamp) */
|
|
31
|
+
downloadedAt: string;
|
|
32
|
+
/** When the model was last used (ISO timestamp) */
|
|
33
|
+
lastUsedAt?: string;
|
|
34
|
+
/** SHA-256 hash of the file for integrity verification */
|
|
35
|
+
sha256?: string;
|
|
36
|
+
/** Source of the download */
|
|
37
|
+
source: ModelSource;
|
|
38
|
+
/** GGUF filename */
|
|
39
|
+
filename: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Persisted model state.
|
|
43
|
+
*/
|
|
44
|
+
export interface ModelState {
|
|
45
|
+
/** Schema version for migrations */
|
|
46
|
+
version: string;
|
|
47
|
+
/** Map of model ID to installed model info */
|
|
48
|
+
installed: Record<string, InstalledModel>;
|
|
49
|
+
/** Currently active/selected model ID */
|
|
50
|
+
activeModelId?: string;
|
|
51
|
+
/** Queue of model IDs pending download */
|
|
52
|
+
downloadQueue: string[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Load model state from disk.
|
|
56
|
+
* Returns default state if file doesn't exist.
|
|
57
|
+
*/
|
|
58
|
+
export declare function loadModelState(): Promise<ModelState>;
|
|
59
|
+
/**
|
|
60
|
+
* Save model state to disk.
|
|
61
|
+
*/
|
|
62
|
+
export declare function saveModelState(state: ModelState): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Add an installed model to state.
|
|
65
|
+
*
|
|
66
|
+
* Note: These operations are not atomic. Ensure single-threaded access
|
|
67
|
+
* or implement file locking for concurrent usage scenarios.
|
|
68
|
+
*/
|
|
69
|
+
export declare function addInstalledModel(model: InstalledModel): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Remove an installed model from state.
|
|
72
|
+
*
|
|
73
|
+
* Note: These operations are not atomic. Ensure single-threaded access
|
|
74
|
+
* or implement file locking for concurrent usage scenarios.
|
|
75
|
+
*/
|
|
76
|
+
export declare function removeInstalledModel(modelId: string): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Get installed model info.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getInstalledModel(modelId: string): Promise<InstalledModel | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Get all installed models.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getAllInstalledModels(): Promise<InstalledModel[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Check if a model is installed.
|
|
87
|
+
*/
|
|
88
|
+
export declare function isModelInstalled(modelId: string): Promise<boolean>;
|
|
89
|
+
/**
|
|
90
|
+
* Update last used timestamp for a model.
|
|
91
|
+
*/
|
|
92
|
+
export declare function updateModelLastUsed(modelId: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Set the active model.
|
|
95
|
+
*/
|
|
96
|
+
export declare function setActiveModel(modelId: string | undefined): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Get the active model ID.
|
|
99
|
+
*/
|
|
100
|
+
export declare function getActiveModelId(): Promise<string | undefined>;
|
|
101
|
+
/**
|
|
102
|
+
* Get the active model info.
|
|
103
|
+
*/
|
|
104
|
+
export declare function getActiveModel(): Promise<InstalledModel | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Add a model to the download queue.
|
|
107
|
+
*/
|
|
108
|
+
export declare function addToDownloadQueue(modelId: string): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Remove a model from the download queue.
|
|
111
|
+
*/
|
|
112
|
+
export declare function removeFromDownloadQueue(modelId: string): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Get the download queue.
|
|
115
|
+
*/
|
|
116
|
+
export declare function getDownloadQueue(): Promise<string[]>;
|
|
117
|
+
/**
|
|
118
|
+
* Sync state with actual filesystem.
|
|
119
|
+
* Removes entries for models that no longer exist on disk.
|
|
120
|
+
*/
|
|
121
|
+
export declare function syncStateWithFilesystem(): Promise<{
|
|
122
|
+
removed: string[];
|
|
123
|
+
kept: string[];
|
|
124
|
+
}>;
|
|
125
|
+
/**
|
|
126
|
+
* Get total size of all installed models.
|
|
127
|
+
*/
|
|
128
|
+
export declare function getTotalInstalledSize(): Promise<number>;
|
|
129
|
+
/**
|
|
130
|
+
* Get count of installed models.
|
|
131
|
+
*/
|
|
132
|
+
export declare function getInstalledModelCount(): Promise<number>;
|
|
133
|
+
/**
|
|
134
|
+
* Register a manually added model file.
|
|
135
|
+
* Used when user places a GGUF file directly in the models directory.
|
|
136
|
+
*/
|
|
137
|
+
export declare function registerManualModel(modelId: string, filename: string, sizeBytes: number, sha256?: string): Promise<void>;
|
|
138
|
+
//# sourceMappingURL=state-manager.d.ts.map
|