@dexto/agent-management 1.4.0 → 1.5.0

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.
Files changed (73) hide show
  1. package/dist/AgentFactory.cjs +1 -2
  2. package/dist/AgentFactory.d.ts +1 -1
  3. package/dist/AgentFactory.d.ts.map +1 -1
  4. package/dist/AgentFactory.js +1 -2
  5. package/dist/config/config-enrichment.cjs +1 -1
  6. package/dist/config/config-enrichment.d.ts +1 -1
  7. package/dist/config/config-enrichment.js +1 -1
  8. package/dist/config/errors.cjs +2 -2
  9. package/dist/config/errors.js +2 -2
  10. package/dist/index.cjs +69 -0
  11. package/dist/index.d.ts +4 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +72 -2
  14. package/dist/installation.cjs +0 -13
  15. package/dist/installation.d.ts +0 -2
  16. package/dist/installation.d.ts.map +1 -1
  17. package/dist/installation.js +0 -13
  18. package/dist/models/custom-models.cjs +43 -2
  19. package/dist/models/custom-models.d.ts +49 -6
  20. package/dist/models/custom-models.d.ts.map +1 -1
  21. package/dist/models/custom-models.js +42 -2
  22. package/dist/models/index.cjs +89 -0
  23. package/dist/models/index.d.ts +11 -0
  24. package/dist/models/index.d.ts.map +1 -0
  25. package/dist/models/index.js +68 -0
  26. package/dist/models/path-resolver.cjs +154 -0
  27. package/dist/models/path-resolver.d.ts +77 -0
  28. package/dist/models/path-resolver.d.ts.map +1 -0
  29. package/dist/models/path-resolver.js +108 -0
  30. package/dist/models/state-manager.cjs +220 -0
  31. package/dist/models/state-manager.d.ts +138 -0
  32. package/dist/models/state-manager.d.ts.map +1 -0
  33. package/dist/models/state-manager.js +184 -0
  34. package/dist/preferences/error-codes.cjs +2 -0
  35. package/dist/preferences/error-codes.d.ts +3 -1
  36. package/dist/preferences/error-codes.d.ts.map +1 -1
  37. package/dist/preferences/error-codes.js +2 -0
  38. package/dist/preferences/index.d.ts +1 -1
  39. package/dist/preferences/index.d.ts.map +1 -1
  40. package/dist/preferences/loader.cjs +32 -6
  41. package/dist/preferences/loader.d.ts +23 -4
  42. package/dist/preferences/loader.d.ts.map +1 -1
  43. package/dist/preferences/loader.js +32 -6
  44. package/dist/preferences/schemas.cjs +21 -3
  45. package/dist/preferences/schemas.d.ts +52 -24
  46. package/dist/preferences/schemas.d.ts.map +1 -1
  47. package/dist/preferences/schemas.js +28 -4
  48. package/dist/registry/registry.cjs +7 -43
  49. package/dist/registry/registry.d.ts +3 -6
  50. package/dist/registry/registry.d.ts.map +1 -1
  51. package/dist/registry/registry.js +7 -43
  52. package/dist/registry/types.d.ts +2 -4
  53. package/dist/registry/types.d.ts.map +1 -1
  54. package/dist/resolver.cjs +20 -20
  55. package/dist/resolver.d.ts +1 -2
  56. package/dist/resolver.d.ts.map +1 -1
  57. package/dist/resolver.js +20 -20
  58. package/dist/utils/api-key-resolver.cjs +19 -1
  59. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  60. package/dist/utils/api-key-resolver.js +19 -1
  61. package/dist/utils/api-key-store.cjs +46 -0
  62. package/dist/utils/api-key-store.d.ts +27 -0
  63. package/dist/utils/api-key-store.d.ts.map +1 -1
  64. package/dist/utils/api-key-store.js +44 -0
  65. package/dist/utils/env-file.cjs +20 -68
  66. package/dist/utils/env-file.d.ts +2 -1
  67. package/dist/utils/env-file.d.ts.map +1 -1
  68. package/dist/utils/env-file.js +20 -68
  69. package/dist/writer.cjs +20 -2
  70. package/dist/writer.d.ts +1 -0
  71. package/dist/writer.d.ts.map +1 -1
  72. package/dist/writer.js +20 -2
  73. package/package.json +2 -2
@@ -1,28 +1,71 @@
1
1
  /**
2
2
  * Custom Models Persistence
3
3
  *
4
- * Manages saved openai-compatible model configurations.
4
+ * Manages saved custom model configurations for openai-compatible and openrouter providers.
5
5
  * Stored in ~/.dexto/models/custom-models.json
6
6
  */
7
7
  import { z } from 'zod';
8
+ /** Providers that support custom models */
9
+ export declare const CUSTOM_MODEL_PROVIDERS: readonly ["openai-compatible", "openrouter", "litellm", "glama", "bedrock", "ollama", "local", "vertex"];
10
+ export type CustomModelProvider = (typeof CUSTOM_MODEL_PROVIDERS)[number];
8
11
  /**
9
- * Schema for a saved openai-compatible model configuration.
12
+ * Schema for a saved custom model configuration.
13
+ * - openai-compatible: requires baseURL, optional per-model apiKey
14
+ * - openrouter: baseURL is auto-injected, maxInputTokens from registry
15
+ * - litellm: requires baseURL, uses LITELLM_API_KEY or per-model override
16
+ * - glama: fixed baseURL, uses GLAMA_API_KEY or per-model override
17
+ * - bedrock: no baseURL, uses AWS credentials from environment
18
+ * - ollama: optional baseURL (defaults to http://localhost:11434)
19
+ * - local: no baseURL, uses local GGUF files via node-llama-cpp
20
+ * - vertex: no baseURL, uses Google Cloud ADC
21
+ *
22
+ * TODO: For hosted deployments, API keys should be stored in a secure
23
+ * key management service (e.g., AWS Secrets Manager, HashiCorp Vault)
24
+ * rather than in the local JSON file. Current approach is suitable for
25
+ * local CLI usage where the file is in ~/.dexto/ (user-private).
10
26
  */
11
- export declare const CustomModelSchema: z.ZodObject<{
27
+ export declare const CustomModelSchema: z.ZodEffects<z.ZodObject<{
12
28
  name: z.ZodString;
13
- baseURL: z.ZodString;
29
+ provider: z.ZodDefault<z.ZodEnum<["openai-compatible", "openrouter", "litellm", "glama", "bedrock", "ollama", "local", "vertex"]>>;
30
+ baseURL: z.ZodOptional<z.ZodString>;
14
31
  displayName: z.ZodOptional<z.ZodString>;
15
32
  maxInputTokens: z.ZodOptional<z.ZodNumber>;
16
33
  maxOutputTokens: z.ZodOptional<z.ZodNumber>;
34
+ apiKey: z.ZodOptional<z.ZodString>;
35
+ filePath: z.ZodOptional<z.ZodString>;
17
36
  }, "strip", z.ZodTypeAny, {
18
37
  name: string;
19
- baseURL: string;
38
+ provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
39
+ apiKey?: string | undefined;
40
+ baseURL?: string | undefined;
41
+ filePath?: string | undefined;
42
+ displayName?: string | undefined;
43
+ maxInputTokens?: number | undefined;
44
+ maxOutputTokens?: number | undefined;
45
+ }, {
46
+ name: string;
47
+ provider?: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
48
+ apiKey?: string | undefined;
49
+ baseURL?: string | undefined;
50
+ filePath?: string | undefined;
51
+ displayName?: string | undefined;
52
+ maxInputTokens?: number | undefined;
53
+ maxOutputTokens?: number | undefined;
54
+ }>, {
55
+ name: string;
56
+ provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
57
+ apiKey?: string | undefined;
58
+ baseURL?: string | undefined;
59
+ filePath?: string | undefined;
20
60
  displayName?: string | undefined;
21
61
  maxInputTokens?: number | undefined;
22
62
  maxOutputTokens?: number | undefined;
23
63
  }, {
24
64
  name: string;
25
- baseURL: string;
65
+ provider?: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
66
+ apiKey?: string | undefined;
67
+ baseURL?: string | undefined;
68
+ filePath?: string | undefined;
26
69
  displayName?: string | undefined;
27
70
  maxInputTokens?: number | undefined;
28
71
  maxOutputTokens?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"custom-models.d.ts","sourceRoot":"","sources":["../../src/models/custom-models.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAM5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAO7D;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAmB/D;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUtE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAG9E"}
1
+ {"version":3,"file":"custom-models.d.ts","sourceRoot":"","sources":["../../src/models/custom-models.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,2CAA2C;AAC3C,eAAO,MAAM,sBAAsB,0GASzB,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CxB,CAAC;AAEP,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAO7D;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAmB/D;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUtE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAG9E"}
@@ -2,12 +2,51 @@ import { z } from "zod";
2
2
  import { promises as fs } from "fs";
3
3
  import * as path from "path";
4
4
  import { getDextoGlobalPath } from "../utils/path.js";
5
+ const CUSTOM_MODEL_PROVIDERS = [
6
+ "openai-compatible",
7
+ "openrouter",
8
+ "litellm",
9
+ "glama",
10
+ "bedrock",
11
+ "ollama",
12
+ "local",
13
+ "vertex"
14
+ ];
5
15
  const CustomModelSchema = z.object({
6
16
  name: z.string().min(1),
7
- baseURL: z.string().url(),
17
+ provider: z.enum(CUSTOM_MODEL_PROVIDERS).default("openai-compatible"),
18
+ baseURL: z.string().url().optional(),
8
19
  displayName: z.string().optional(),
9
20
  maxInputTokens: z.number().int().positive().optional(),
10
- maxOutputTokens: z.number().int().positive().optional()
21
+ maxOutputTokens: z.number().int().positive().optional(),
22
+ // Optional per-model API key. For openai-compatible this is the primary key source.
23
+ // For litellm/glama/openrouter this overrides the provider-level env var key.
24
+ apiKey: z.string().optional(),
25
+ // File path for local GGUF models. Required when provider is 'local'.
26
+ // Stores the absolute path to the .gguf file on disk.
27
+ filePath: z.string().optional()
28
+ }).superRefine((data, ctx) => {
29
+ if ((data.provider === "openai-compatible" || data.provider === "litellm") && !data.baseURL) {
30
+ ctx.addIssue({
31
+ code: z.ZodIssueCode.custom,
32
+ path: ["baseURL"],
33
+ message: `Base URL is required for ${data.provider} provider`
34
+ });
35
+ }
36
+ if (data.provider === "local" && !data.filePath) {
37
+ ctx.addIssue({
38
+ code: z.ZodIssueCode.custom,
39
+ path: ["filePath"],
40
+ message: "File path is required for local provider"
41
+ });
42
+ }
43
+ if (data.provider === "local" && data.filePath && !data.filePath.endsWith(".gguf")) {
44
+ ctx.addIssue({
45
+ code: z.ZodIssueCode.custom,
46
+ path: ["filePath"],
47
+ message: "File path must be a .gguf file"
48
+ });
49
+ }
11
50
  });
12
51
  const StorageSchema = z.object({
13
52
  version: z.literal(1),
@@ -68,6 +107,7 @@ async function writeCustomModels(models) {
68
107
  await fs.writeFile(filePath, JSON.stringify({ version: 1, models }, null, 2), "utf-8");
69
108
  }
70
109
  export {
110
+ CUSTOM_MODEL_PROVIDERS,
71
111
  CustomModelSchema,
72
112
  deleteCustomModel,
73
113
  getCustomModel,
@@ -0,0 +1,89 @@
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 models_exports = {};
20
+ __export(models_exports, {
21
+ addInstalledModel: () => import_state_manager.addInstalledModel,
22
+ addToDownloadQueue: () => import_state_manager.addToDownloadQueue,
23
+ deleteModelDirectory: () => import_path_resolver.deleteModelDirectory,
24
+ ensureModelDirectory: () => import_path_resolver.ensureModelDirectory,
25
+ ensureModelsDirectory: () => import_path_resolver.ensureModelsDirectory,
26
+ formatSize: () => import_path_resolver.formatSize,
27
+ getActiveModel: () => import_state_manager.getActiveModel,
28
+ getActiveModelId: () => import_state_manager.getActiveModelId,
29
+ getAllInstalledModels: () => import_state_manager.getAllInstalledModels,
30
+ getDownloadQueue: () => import_state_manager.getDownloadQueue,
31
+ getInstalledModel: () => import_state_manager.getInstalledModel,
32
+ getInstalledModelCount: () => import_state_manager.getInstalledModelCount,
33
+ getModelDirectory: () => import_path_resolver.getModelDirectory,
34
+ getModelFilePath: () => import_path_resolver.getModelFilePath,
35
+ getModelFileSize: () => import_path_resolver.getModelFileSize,
36
+ getModelStatePath: () => import_path_resolver.getModelStatePath,
37
+ getModelTempDirectory: () => import_path_resolver.getModelTempDirectory,
38
+ getModelsDirectory: () => import_path_resolver.getModelsDirectory,
39
+ getModelsDiskUsage: () => import_path_resolver.getModelsDiskUsage,
40
+ getTotalInstalledSize: () => import_state_manager.getTotalInstalledSize,
41
+ isModelInstalled: () => import_state_manager.isModelInstalled,
42
+ listModelDirectories: () => import_path_resolver.listModelDirectories,
43
+ loadModelState: () => import_state_manager.loadModelState,
44
+ modelFileExists: () => import_path_resolver.modelFileExists,
45
+ registerManualModel: () => import_state_manager.registerManualModel,
46
+ removeFromDownloadQueue: () => import_state_manager.removeFromDownloadQueue,
47
+ removeInstalledModel: () => import_state_manager.removeInstalledModel,
48
+ saveModelState: () => import_state_manager.saveModelState,
49
+ setActiveModel: () => import_state_manager.setActiveModel,
50
+ syncStateWithFilesystem: () => import_state_manager.syncStateWithFilesystem,
51
+ updateModelLastUsed: () => import_state_manager.updateModelLastUsed
52
+ });
53
+ module.exports = __toCommonJS(models_exports);
54
+ var import_path_resolver = require("./path-resolver.js");
55
+ var import_state_manager = require("./state-manager.js");
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ addInstalledModel,
59
+ addToDownloadQueue,
60
+ deleteModelDirectory,
61
+ ensureModelDirectory,
62
+ ensureModelsDirectory,
63
+ formatSize,
64
+ getActiveModel,
65
+ getActiveModelId,
66
+ getAllInstalledModels,
67
+ getDownloadQueue,
68
+ getInstalledModel,
69
+ getInstalledModelCount,
70
+ getModelDirectory,
71
+ getModelFilePath,
72
+ getModelFileSize,
73
+ getModelStatePath,
74
+ getModelTempDirectory,
75
+ getModelsDirectory,
76
+ getModelsDiskUsage,
77
+ getTotalInstalledSize,
78
+ isModelInstalled,
79
+ listModelDirectories,
80
+ loadModelState,
81
+ modelFileExists,
82
+ registerManualModel,
83
+ removeFromDownloadQueue,
84
+ removeInstalledModel,
85
+ saveModelState,
86
+ setActiveModel,
87
+ syncStateWithFilesystem,
88
+ updateModelLastUsed
89
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Model management for local GGUF models.
3
+ *
4
+ * This module handles:
5
+ * - Path resolution for ~/.dexto/models/
6
+ * - State tracking for installed models
7
+ * - Download queue management
8
+ */
9
+ export { getModelsDirectory, getModelFilePath, getModelDirectory, getModelStatePath, getModelTempDirectory, ensureModelsDirectory, ensureModelDirectory, modelFileExists, getModelFileSize, deleteModelDirectory, listModelDirectories, getModelsDiskUsage, formatSize, } from './path-resolver.js';
10
+ export { type ModelSource, type InstalledModel, type ModelState, loadModelState, saveModelState, addInstalledModel, removeInstalledModel, getInstalledModel, getAllInstalledModels, isModelInstalled, updateModelLastUsed, setActiveModel, getActiveModelId, getActiveModel, addToDownloadQueue, removeFromDownloadQueue, getDownloadQueue, syncStateWithFilesystem, getTotalInstalledSize, getInstalledModelCount, registerManualModel, } from './state-manager.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACH,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,GACb,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,GACtB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,68 @@
1
+ import {
2
+ getModelsDirectory,
3
+ getModelFilePath,
4
+ getModelDirectory,
5
+ getModelStatePath,
6
+ getModelTempDirectory,
7
+ ensureModelsDirectory,
8
+ ensureModelDirectory,
9
+ modelFileExists,
10
+ getModelFileSize,
11
+ deleteModelDirectory,
12
+ listModelDirectories,
13
+ getModelsDiskUsage,
14
+ formatSize
15
+ } from "./path-resolver.js";
16
+ import {
17
+ loadModelState,
18
+ saveModelState,
19
+ addInstalledModel,
20
+ removeInstalledModel,
21
+ getInstalledModel,
22
+ getAllInstalledModels,
23
+ isModelInstalled,
24
+ updateModelLastUsed,
25
+ setActiveModel,
26
+ getActiveModelId,
27
+ getActiveModel,
28
+ addToDownloadQueue,
29
+ removeFromDownloadQueue,
30
+ getDownloadQueue,
31
+ syncStateWithFilesystem,
32
+ getTotalInstalledSize,
33
+ getInstalledModelCount,
34
+ registerManualModel
35
+ } from "./state-manager.js";
36
+ export {
37
+ addInstalledModel,
38
+ addToDownloadQueue,
39
+ deleteModelDirectory,
40
+ ensureModelDirectory,
41
+ ensureModelsDirectory,
42
+ formatSize,
43
+ getActiveModel,
44
+ getActiveModelId,
45
+ getAllInstalledModels,
46
+ getDownloadQueue,
47
+ getInstalledModel,
48
+ getInstalledModelCount,
49
+ getModelDirectory,
50
+ getModelFilePath,
51
+ getModelFileSize,
52
+ getModelStatePath,
53
+ getModelTempDirectory,
54
+ getModelsDirectory,
55
+ getModelsDiskUsage,
56
+ getTotalInstalledSize,
57
+ isModelInstalled,
58
+ listModelDirectories,
59
+ loadModelState,
60
+ modelFileExists,
61
+ registerManualModel,
62
+ removeFromDownloadQueue,
63
+ removeInstalledModel,
64
+ saveModelState,
65
+ setActiveModel,
66
+ syncStateWithFilesystem,
67
+ updateModelLastUsed
68
+ };
@@ -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
+ };