@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.
Files changed (78) 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 +50 -1
  6. package/dist/config/config-enrichment.d.ts +2 -2
  7. package/dist/config/config-enrichment.d.ts.map +1 -1
  8. package/dist/config/config-enrichment.js +51 -3
  9. package/dist/config/discover-prompts.cjs +13 -0
  10. package/dist/config/discover-prompts.d.ts +13 -0
  11. package/dist/config/discover-prompts.d.ts.map +1 -1
  12. package/dist/config/discover-prompts.js +12 -0
  13. package/dist/config/errors.cjs +2 -2
  14. package/dist/config/errors.js +2 -2
  15. package/dist/index.cjs +69 -0
  16. package/dist/index.d.ts +4 -3
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +72 -2
  19. package/dist/installation.cjs +0 -13
  20. package/dist/installation.d.ts +0 -2
  21. package/dist/installation.d.ts.map +1 -1
  22. package/dist/installation.js +0 -13
  23. package/dist/models/custom-models.cjs +46 -2
  24. package/dist/models/custom-models.d.ts +54 -6
  25. package/dist/models/custom-models.d.ts.map +1 -1
  26. package/dist/models/custom-models.js +45 -2
  27. package/dist/models/index.cjs +89 -0
  28. package/dist/models/index.d.ts +11 -0
  29. package/dist/models/index.d.ts.map +1 -0
  30. package/dist/models/index.js +68 -0
  31. package/dist/models/path-resolver.cjs +154 -0
  32. package/dist/models/path-resolver.d.ts +77 -0
  33. package/dist/models/path-resolver.d.ts.map +1 -0
  34. package/dist/models/path-resolver.js +108 -0
  35. package/dist/models/state-manager.cjs +220 -0
  36. package/dist/models/state-manager.d.ts +138 -0
  37. package/dist/models/state-manager.d.ts.map +1 -0
  38. package/dist/models/state-manager.js +184 -0
  39. package/dist/preferences/error-codes.cjs +2 -0
  40. package/dist/preferences/error-codes.d.ts +3 -1
  41. package/dist/preferences/error-codes.d.ts.map +1 -1
  42. package/dist/preferences/error-codes.js +2 -0
  43. package/dist/preferences/index.d.ts +1 -1
  44. package/dist/preferences/index.d.ts.map +1 -1
  45. package/dist/preferences/loader.cjs +35 -6
  46. package/dist/preferences/loader.d.ts +25 -4
  47. package/dist/preferences/loader.d.ts.map +1 -1
  48. package/dist/preferences/loader.js +35 -6
  49. package/dist/preferences/schemas.cjs +24 -3
  50. package/dist/preferences/schemas.d.ts +64 -24
  51. package/dist/preferences/schemas.d.ts.map +1 -1
  52. package/dist/preferences/schemas.js +31 -4
  53. package/dist/registry/registry.cjs +7 -43
  54. package/dist/registry/registry.d.ts +3 -6
  55. package/dist/registry/registry.d.ts.map +1 -1
  56. package/dist/registry/registry.js +7 -43
  57. package/dist/registry/types.d.ts +2 -4
  58. package/dist/registry/types.d.ts.map +1 -1
  59. package/dist/resolver.cjs +20 -20
  60. package/dist/resolver.d.ts +1 -2
  61. package/dist/resolver.d.ts.map +1 -1
  62. package/dist/resolver.js +20 -20
  63. package/dist/utils/api-key-resolver.cjs +19 -1
  64. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  65. package/dist/utils/api-key-resolver.js +19 -1
  66. package/dist/utils/api-key-store.cjs +46 -0
  67. package/dist/utils/api-key-store.d.ts +27 -0
  68. package/dist/utils/api-key-store.d.ts.map +1 -1
  69. package/dist/utils/api-key-store.js +44 -0
  70. package/dist/utils/env-file.cjs +20 -68
  71. package/dist/utils/env-file.d.ts +2 -1
  72. package/dist/utils/env-file.d.ts.map +1 -1
  73. package/dist/utils/env-file.js +20 -68
  74. package/dist/writer.cjs +20 -2
  75. package/dist/writer.d.ts +1 -0
  76. package/dist/writer.d.ts.map +1 -1
  77. package/dist/writer.js +20 -2
  78. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -59,7 +59,9 @@ import {
59
59
  import {
60
60
  saveProviderApiKey,
61
61
  getProviderKeyStatus,
62
- listProviderKeyStatus
62
+ listProviderKeyStatus,
63
+ determineApiKeyStorage,
64
+ SHARED_API_KEY_PROVIDERS
63
65
  } from "./utils/api-key-store.js";
64
66
  import {
65
67
  resolveApiKeyForProvider,
@@ -72,11 +74,46 @@ import {
72
74
  deleteCustomModel,
73
75
  getCustomModel,
74
76
  getCustomModelsPath,
75
- CustomModelSchema
77
+ CustomModelSchema,
78
+ CUSTOM_MODEL_PROVIDERS
76
79
  } from "./models/custom-models.js";
80
+ import {
81
+ getModelsDirectory,
82
+ getModelFilePath,
83
+ getModelDirectory,
84
+ getModelStatePath,
85
+ getModelTempDirectory,
86
+ ensureModelsDirectory,
87
+ ensureModelDirectory,
88
+ modelFileExists,
89
+ getModelFileSize,
90
+ deleteModelDirectory,
91
+ listModelDirectories,
92
+ getModelsDiskUsage,
93
+ formatSize,
94
+ loadModelState,
95
+ saveModelState,
96
+ addInstalledModel,
97
+ removeInstalledModel,
98
+ getInstalledModel,
99
+ getAllInstalledModels,
100
+ isModelInstalled,
101
+ updateModelLastUsed,
102
+ setActiveModel,
103
+ getActiveModelId,
104
+ getActiveModel,
105
+ addToDownloadQueue,
106
+ removeFromDownloadQueue,
107
+ getDownloadQueue,
108
+ syncStateWithFilesystem,
109
+ getTotalInstalledSize,
110
+ getInstalledModelCount,
111
+ registerManualModel
112
+ } from "./models/index.js";
77
113
  export {
78
114
  AgentFactory,
79
115
  AgentManager,
116
+ CUSTOM_MODEL_PROVIDERS,
80
117
  ConfigError,
81
118
  ConfigErrorCode,
82
119
  CustomModelSchema,
@@ -85,39 +122,68 @@ export {
85
122
  PreferenceErrorCode,
86
123
  RegistryError,
87
124
  RegistryErrorCode,
125
+ SHARED_API_KEY_PROVIDERS,
126
+ addInstalledModel,
88
127
  addPromptToAgentConfig,
128
+ addToDownloadQueue,
89
129
  copyDirectory,
90
130
  createInitialPreferences,
91
131
  deleteCustomModel,
132
+ deleteModelDirectory,
92
133
  deletePromptByMetadata,
93
134
  deriveAgentId,
94
135
  deriveDisplayName,
136
+ determineApiKeyStorage,
95
137
  enrichAgentConfig,
96
138
  ensureDextoGlobalDirectory,
139
+ ensureModelDirectory,
140
+ ensureModelsDirectory,
97
141
  findDextoProjectRoot,
98
142
  findDextoSourceRoot,
99
143
  findPackageRoot,
144
+ formatSize,
145
+ getActiveModel,
146
+ getActiveModelId,
100
147
  getAgentRegistry,
148
+ getAllInstalledModels,
101
149
  getCustomModel,
102
150
  getCustomModelsPath,
103
151
  getDextoEnvPath,
104
152
  getDextoGlobalPath,
105
153
  getDextoPath,
154
+ getDownloadQueue,
106
155
  getExecutionContext,
107
156
  getGlobalPreferencesPath,
157
+ getInstalledModel,
158
+ getInstalledModelCount,
159
+ getModelDirectory,
160
+ getModelFilePath,
161
+ getModelFileSize,
162
+ getModelStatePath,
163
+ getModelTempDirectory,
164
+ getModelsDirectory,
165
+ getModelsDiskUsage,
108
166
  getPrimaryApiKeyEnvVar,
109
167
  getProviderKeyStatus,
168
+ getTotalInstalledSize,
110
169
  globalPreferencesExist,
111
170
  installBundledAgent,
112
171
  installCustomAgent,
172
+ isModelInstalled,
113
173
  isPath,
114
174
  listInstalledAgents,
175
+ listModelDirectories,
115
176
  listProviderKeyStatus,
116
177
  loadAgentConfig,
117
178
  loadBundledRegistryAgents,
118
179
  loadCustomModels,
119
180
  loadGlobalPreferences,
181
+ loadModelState,
182
+ modelFileExists,
183
+ registerManualModel,
120
184
  reloadAgentConfigFromFile,
185
+ removeFromDownloadQueue,
186
+ removeInstalledModel,
121
187
  removeMcpServerFromConfig,
122
188
  removePromptFromAgentConfig,
123
189
  resolveAgentPath,
@@ -125,13 +191,17 @@ export {
125
191
  resolveBundledScript,
126
192
  saveCustomModel,
127
193
  saveGlobalPreferences,
194
+ saveModelState,
128
195
  saveProviderApiKey,
196
+ setActiveModel,
197
+ syncStateWithFilesystem,
129
198
  uninstallAgent,
130
199
  updateAgentConfigFile,
131
200
  updateDefaultAgentPreference,
132
201
  updateEnvFile,
133
202
  updateGlobalPreferences,
134
203
  updateMcpServerField,
204
+ updateModelLastUsed,
135
205
  walkUpDirectories,
136
206
  writeConfigFile,
137
207
  writeLLMPreferences,
@@ -38,8 +38,6 @@ var import_fs = require("fs");
38
38
  var import_path = __toESM(require("path"), 1);
39
39
  var import_core = require("@dexto/core");
40
40
  var import_path2 = require("./utils/path.js");
41
- var import_loader = require("./preferences/loader.js");
42
- var import_writer = require("./writer.js");
43
41
  var import_errors = require("./registry/errors.js");
44
42
  var import_errors2 = require("./config/errors.js");
45
43
  function getAgentsDir(options) {
@@ -103,17 +101,6 @@ async function installBundledAgent(agentId, options) {
103
101
  }
104
102
  await import_fs.promises.rename(tempDir, targetDir);
105
103
  import_core.logger.info(`\u2713 Installed agent '${agentId}' to ${targetDir}`);
106
- if (options?.injectPreferences !== false) {
107
- try {
108
- const preferences = await (0, import_loader.loadGlobalPreferences)();
109
- await (0, import_writer.writePreferencesToAgent)(targetDir, preferences);
110
- import_core.logger.info(`\u2713 Applied global preferences to '${agentId}'`);
111
- } catch (error) {
112
- import_core.logger.warn(
113
- `Failed to inject preferences: ${error instanceof Error ? error.message : String(error)}`
114
- );
115
- }
116
- }
117
104
  const userRegistryPath = getUserRegistryPath(agentsDir);
118
105
  const userRegistry = await loadUserRegistry(userRegistryPath);
119
106
  if (!userRegistry.agents.some((a) => a.id === agentId)) {
@@ -2,8 +2,6 @@ import type { AgentMetadata } from './AgentManager.js';
2
2
  export interface InstallOptions {
3
3
  /** Directory where agents are stored (default: ~/.dexto/agents) */
4
4
  agentsDir?: string;
5
- /** Whether to inject global preferences into agent config (default: true) */
6
- injectPreferences?: boolean;
7
5
  }
8
6
  /**
9
7
  * Install agent from bundled registry to local directory
@@ -1 +1 @@
1
- {"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../src/installation.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC3B,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAuCD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CA0GjB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC,EACzE,OAAO,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CA2FjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B7F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYrF"}
1
+ {"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../src/installation.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC3B,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAuCD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CA6FjB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACpC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC,EACzE,OAAO,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CA2FjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B7F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYrF"}
@@ -2,8 +2,6 @@ import { promises as fs } from "fs";
2
2
  import path from "path";
3
3
  import { logger } from "@dexto/core";
4
4
  import { getDextoGlobalPath, resolveBundledScript, copyDirectory } from "./utils/path.js";
5
- import { loadGlobalPreferences } from "./preferences/loader.js";
6
- import { writePreferencesToAgent } from "./writer.js";
7
5
  import { RegistryError } from "./registry/errors.js";
8
6
  import { ConfigError } from "./config/errors.js";
9
7
  function getAgentsDir(options) {
@@ -67,17 +65,6 @@ async function installBundledAgent(agentId, options) {
67
65
  }
68
66
  await fs.rename(tempDir, targetDir);
69
67
  logger.info(`\u2713 Installed agent '${agentId}' to ${targetDir}`);
70
- if (options?.injectPreferences !== false) {
71
- try {
72
- const preferences = await loadGlobalPreferences();
73
- await writePreferencesToAgent(targetDir, preferences);
74
- logger.info(`\u2713 Applied global preferences to '${agentId}'`);
75
- } catch (error) {
76
- logger.warn(
77
- `Failed to inject preferences: ${error instanceof Error ? error.message : String(error)}`
78
- );
79
- }
80
- }
81
68
  const userRegistryPath = getUserRegistryPath(agentsDir);
82
69
  const userRegistry = await loadUserRegistry(userRegistryPath);
83
70
  if (!userRegistry.agents.some((a) => a.id === agentId)) {
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var custom_models_exports = {};
30
30
  __export(custom_models_exports, {
31
+ CUSTOM_MODEL_PROVIDERS: () => CUSTOM_MODEL_PROVIDERS,
31
32
  CustomModelSchema: () => CustomModelSchema,
32
33
  deleteCustomModel: () => deleteCustomModel,
33
34
  getCustomModel: () => getCustomModel,
@@ -40,12 +41,54 @@ var import_zod = require("zod");
40
41
  var import_fs = require("fs");
41
42
  var path = __toESM(require("path"), 1);
42
43
  var import_path = require("../utils/path.js");
44
+ const CUSTOM_MODEL_PROVIDERS = [
45
+ "openai-compatible",
46
+ "openrouter",
47
+ "litellm",
48
+ "glama",
49
+ "bedrock",
50
+ "ollama",
51
+ "local",
52
+ "vertex"
53
+ ];
43
54
  const CustomModelSchema = import_zod.z.object({
44
55
  name: import_zod.z.string().min(1),
45
- baseURL: import_zod.z.string().url(),
56
+ provider: import_zod.z.enum(CUSTOM_MODEL_PROVIDERS).default("openai-compatible"),
57
+ baseURL: import_zod.z.string().url().optional(),
46
58
  displayName: import_zod.z.string().optional(),
47
59
  maxInputTokens: import_zod.z.number().int().positive().optional(),
48
- maxOutputTokens: import_zod.z.number().int().positive().optional()
60
+ maxOutputTokens: import_zod.z.number().int().positive().optional(),
61
+ // Optional per-model API key. For openai-compatible this is the primary key source.
62
+ // For litellm/glama/openrouter this overrides the provider-level env var key.
63
+ apiKey: import_zod.z.string().optional(),
64
+ // File path for local GGUF models. Required when provider is 'local'.
65
+ // Stores the absolute path to the .gguf file on disk.
66
+ filePath: import_zod.z.string().optional(),
67
+ // OpenAI reasoning effort level for reasoning-capable models (o1, o3, codex, gpt-5.x).
68
+ // Controls how many reasoning tokens the model generates before producing a response.
69
+ reasoningEffort: import_zod.z.enum(["none", "minimal", "low", "medium", "high", "xhigh"]).optional()
70
+ }).superRefine((data, ctx) => {
71
+ if ((data.provider === "openai-compatible" || data.provider === "litellm") && !data.baseURL) {
72
+ ctx.addIssue({
73
+ code: import_zod.z.ZodIssueCode.custom,
74
+ path: ["baseURL"],
75
+ message: `Base URL is required for ${data.provider} provider`
76
+ });
77
+ }
78
+ if (data.provider === "local" && !data.filePath) {
79
+ ctx.addIssue({
80
+ code: import_zod.z.ZodIssueCode.custom,
81
+ path: ["filePath"],
82
+ message: "File path is required for local provider"
83
+ });
84
+ }
85
+ if (data.provider === "local" && data.filePath && !data.filePath.endsWith(".gguf")) {
86
+ ctx.addIssue({
87
+ code: import_zod.z.ZodIssueCode.custom,
88
+ path: ["filePath"],
89
+ message: "File path must be a .gguf file"
90
+ });
91
+ }
49
92
  });
50
93
  const StorageSchema = import_zod.z.object({
51
94
  version: import_zod.z.literal(1),
@@ -107,6 +150,7 @@ async function writeCustomModels(models) {
107
150
  }
108
151
  // Annotate the CommonJS export names for ESM import in node:
109
152
  0 && (module.exports = {
153
+ CUSTOM_MODEL_PROVIDERS,
110
154
  CustomModelSchema,
111
155
  deleteCustomModel,
112
156
  getCustomModel,
@@ -1,28 +1,76 @@
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>;
36
+ reasoningEffort: z.ZodOptional<z.ZodEnum<["none", "minimal", "low", "medium", "high", "xhigh"]>>;
17
37
  }, "strip", z.ZodTypeAny, {
18
38
  name: string;
19
- baseURL: string;
39
+ provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
40
+ apiKey?: string | undefined;
41
+ baseURL?: string | undefined;
42
+ reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
43
+ filePath?: string | undefined;
44
+ displayName?: string | undefined;
45
+ maxInputTokens?: number | undefined;
46
+ maxOutputTokens?: number | undefined;
47
+ }, {
48
+ name: string;
49
+ provider?: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
50
+ apiKey?: string | undefined;
51
+ baseURL?: string | undefined;
52
+ reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
53
+ filePath?: string | undefined;
54
+ displayName?: string | undefined;
55
+ maxInputTokens?: number | undefined;
56
+ maxOutputTokens?: number | undefined;
57
+ }>, {
58
+ name: string;
59
+ provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
60
+ apiKey?: string | undefined;
61
+ baseURL?: string | undefined;
62
+ reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
63
+ filePath?: string | undefined;
20
64
  displayName?: string | undefined;
21
65
  maxInputTokens?: number | undefined;
22
66
  maxOutputTokens?: number | undefined;
23
67
  }, {
24
68
  name: string;
25
- baseURL: string;
69
+ provider?: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
70
+ apiKey?: string | undefined;
71
+ baseURL?: string | undefined;
72
+ reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
73
+ filePath?: string | undefined;
26
74
  displayName?: string | undefined;
27
75
  maxInputTokens?: number | undefined;
28
76
  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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CxB,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,54 @@ 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
+ // OpenAI reasoning effort level for reasoning-capable models (o1, o3, codex, gpt-5.x).
29
+ // Controls how many reasoning tokens the model generates before producing a response.
30
+ reasoningEffort: z.enum(["none", "minimal", "low", "medium", "high", "xhigh"]).optional()
31
+ }).superRefine((data, ctx) => {
32
+ if ((data.provider === "openai-compatible" || data.provider === "litellm") && !data.baseURL) {
33
+ ctx.addIssue({
34
+ code: z.ZodIssueCode.custom,
35
+ path: ["baseURL"],
36
+ message: `Base URL is required for ${data.provider} provider`
37
+ });
38
+ }
39
+ if (data.provider === "local" && !data.filePath) {
40
+ ctx.addIssue({
41
+ code: z.ZodIssueCode.custom,
42
+ path: ["filePath"],
43
+ message: "File path is required for local provider"
44
+ });
45
+ }
46
+ if (data.provider === "local" && data.filePath && !data.filePath.endsWith(".gguf")) {
47
+ ctx.addIssue({
48
+ code: z.ZodIssueCode.custom,
49
+ path: ["filePath"],
50
+ message: "File path must be a .gguf file"
51
+ });
52
+ }
11
53
  });
12
54
  const StorageSchema = z.object({
13
55
  version: z.literal(1),
@@ -68,6 +110,7 @@ async function writeCustomModels(models) {
68
110
  await fs.writeFile(filePath, JSON.stringify({ version: 1, models }, null, 2), "utf-8");
69
111
  }
70
112
  export {
113
+ CUSTOM_MODEL_PROVIDERS,
71
114
  CustomModelSchema,
72
115
  deleteCustomModel,
73
116
  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
+ };