@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
@@ -23,12 +23,31 @@ export declare function globalPreferencesExist(): boolean;
23
23
  * @returns Absolute path to preferences.yml
24
24
  */
25
25
  export declare function getGlobalPreferencesPath(): string;
26
+ /**
27
+ * Options for creating initial preferences
28
+ */
29
+ export interface CreatePreferencesOptions {
30
+ provider: LLMProvider;
31
+ model: string;
32
+ /** API key env var (optional for providers like Ollama that don't need auth) */
33
+ apiKeyVar?: string;
34
+ defaultAgent?: string;
35
+ defaultMode?: 'cli' | 'web' | 'server' | 'discord' | 'telegram' | 'mcp';
36
+ baseURL?: string;
37
+ setupCompleted?: boolean;
38
+ /** Whether API key setup was skipped and needs to be configured later */
39
+ apiKeyPending?: boolean;
40
+ /** Whether baseURL setup was skipped and needs to be configured later */
41
+ baseURLPending?: boolean;
42
+ }
26
43
  /**
27
44
  * Create initial preferences from setup data
28
- * @param provider Selected LLM provider
29
- * @param model Selected model
30
- * @param apiKeyVar Environment variable name for API key
31
- * @param defaultAgent Optional default agent name
45
+ * @param options Configuration options for preferences
46
+ */
47
+ export declare function createInitialPreferences(options: CreatePreferencesOptions): GlobalPreferences;
48
+ /**
49
+ * Create initial preferences from setup data (legacy signature)
50
+ * @deprecated Use options object instead
32
51
  */
33
52
  export declare function createInitialPreferences(provider: LLMProvider, model: string, apiKeyVar: string, defaultAgent?: string): GlobalPreferences;
34
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/preferences/loader.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI/E;;;;;GAKG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA+BxE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCzF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,YAAY,GAAE,MAAwB,GACvC,iBAAiB,CAenB;AAED;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACnC,GAAG,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CACzC,OAAO,EAAE,wBAAwB,GAClC,OAAO,CAAC,iBAAiB,CAAC,CA2B5B"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/preferences/loader.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI/E;;;;;GAKG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA+BxE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCzF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAAC;AAE/F;;;GAGG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,GACtB,iBAAiB,CAAC;AA2DrB;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACnC,GAAG,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CACzC,OAAO,EAAE,wBAAwB,GAClC,OAAO,CAAC,iBAAiB,CAAC,CA2B5B"}
@@ -38,7 +38,7 @@ async function saveGlobalPreferences(preferences) {
38
38
  throw PreferenceError.validationFailed(validation.error);
39
39
  }
40
40
  try {
41
- logger.info(`Saving global preferences to: ${preferencesPath}`);
41
+ logger.debug(`Saving global preferences to: ${preferencesPath}`);
42
42
  const dextoDir = getDextoGlobalPath("");
43
43
  await fs.mkdir(dextoDir, { recursive: true });
44
44
  const yamlContent = stringifyYaml(preferences, {
@@ -47,7 +47,7 @@ async function saveGlobalPreferences(preferences) {
47
47
  minContentWidth: 20
48
48
  });
49
49
  await fs.writeFile(preferencesPath, yamlContent, "utf-8");
50
- logger.info(
50
+ logger.debug(
51
51
  `\u2713 Saved global preferences ${JSON.stringify(preferences)} to: ${preferencesPath}`
52
52
  );
53
53
  } catch (error) {
@@ -64,20 +64,46 @@ function globalPreferencesExist() {
64
64
  function getGlobalPreferencesPath() {
65
65
  return getDextoGlobalPath(PREFERENCES_FILE);
66
66
  }
67
- function createInitialPreferences(provider, model, apiKeyVar, defaultAgent = "default-agent") {
67
+ function createInitialPreferences(providerOrOptions, model, apiKeyVar, defaultAgent = "coding-agent") {
68
+ if (typeof providerOrOptions === "object") {
69
+ const opts = providerOrOptions;
70
+ const llmConfig = {
71
+ provider: opts.provider,
72
+ model: opts.model
73
+ };
74
+ if (opts.apiKeyVar) {
75
+ llmConfig.apiKey = `$${opts.apiKeyVar}`;
76
+ }
77
+ if (opts.baseURL) {
78
+ llmConfig.baseURL = opts.baseURL;
79
+ }
80
+ return {
81
+ llm: llmConfig,
82
+ defaults: {
83
+ defaultAgent: opts.defaultAgent || "coding-agent",
84
+ defaultMode: opts.defaultMode || "web"
85
+ },
86
+ setup: {
87
+ completed: opts.setupCompleted ?? true,
88
+ apiKeyPending: opts.apiKeyPending ?? false,
89
+ baseURLPending: opts.baseURLPending ?? false
90
+ }
91
+ };
92
+ }
68
93
  return {
69
94
  llm: {
70
- provider,
95
+ provider: providerOrOptions,
71
96
  model,
72
97
  apiKey: `$${apiKeyVar}`
73
98
  },
74
99
  defaults: {
75
100
  defaultAgent,
76
101
  defaultMode: "web"
77
- // Default to web mode
78
102
  },
79
103
  setup: {
80
- completed: true
104
+ completed: true,
105
+ apiKeyPending: false,
106
+ baseURLPending: false
81
107
  }
82
108
  };
83
109
  }
@@ -36,9 +36,13 @@ const PreferenceLLMSchema = import_zod.z.object({
36
36
  apiKey: import_zod.z.string().regex(
37
37
  /^\$[A-Z_][A-Z0-9_]*$/,
38
38
  "Must be environment variable reference (e.g., $OPENAI_API_KEY)"
39
- ).describe("Environment variable reference for API key")
39
+ ).optional().describe(
40
+ "Environment variable reference for API key (optional for local providers like Ollama)"
41
+ ),
42
+ baseURL: import_zod.z.string().url("Must be a valid URL (e.g., http://localhost:11434/v1)").optional().describe("Custom base URL for providers that support it (openai-compatible, litellm)")
40
43
  }).strict().superRefine((data, ctx) => {
41
- if (!(0, import_core.isValidProviderModel)(data.provider, data.model)) {
44
+ const skipModelValidation = (0, import_core.acceptsAnyModel)(data.provider) || (0, import_core.supportsCustomModels)(data.provider);
45
+ if (!skipModelValidation && !(0, import_core.isValidProviderModel)(data.provider, data.model)) {
42
46
  const supportedModels = (0, import_core.getSupportedModels)(data.provider);
43
47
  ctx.addIssue({
44
48
  code: import_zod.z.ZodIssueCode.custom,
@@ -51,13 +55,27 @@ const PreferenceLLMSchema = import_zod.z.object({
51
55
  }
52
56
  });
53
57
  }
58
+ if (data.baseURL && !(0, import_core.supportsBaseURL)(data.provider)) {
59
+ ctx.addIssue({
60
+ code: import_zod.z.ZodIssueCode.custom,
61
+ path: ["baseURL"],
62
+ message: `Provider '${data.provider}' does not support custom baseURL. Use 'openai-compatible' for custom endpoints.`,
63
+ params: {
64
+ code: import_error_codes.PreferenceErrorCode.INVALID_PREFERENCE_VALUE,
65
+ scope: "preference",
66
+ type: import_core4.ErrorType.USER
67
+ }
68
+ });
69
+ }
54
70
  });
55
71
  const PreferenceDefaultsSchema = import_zod.z.object({
56
72
  defaultAgent: import_zod.z.string().min(1).describe("Default agent name for global CLI usage (required)"),
57
73
  defaultMode: import_zod.z.enum(["cli", "web", "server", "discord", "telegram", "mcp"]).default("web").describe("Default run mode when --mode flag is not specified (default: web)")
58
74
  }).strict();
59
75
  const PreferenceSetupSchema = import_zod.z.object({
60
- completed: import_zod.z.boolean().default(false).describe("Whether initial setup has been completed")
76
+ completed: import_zod.z.boolean().default(false).describe("Whether initial setup has been completed"),
77
+ apiKeyPending: import_zod.z.boolean().default(false).describe("Whether API key setup was skipped and needs to be configured later"),
78
+ baseURLPending: import_zod.z.boolean().default(false).describe("Whether baseURL setup was skipped and needs to be configured later")
61
79
  }).strict();
62
80
  const GlobalPreferencesSchema = import_zod.z.object({
63
81
  llm: PreferenceLLMSchema.describe("LLM configuration preferences"),
@@ -1,24 +1,29 @@
1
1
  import { z } from 'zod';
2
2
  export declare const PreferenceLLMSchema: z.ZodEffects<z.ZodObject<{
3
- provider: z.ZodEnum<["openai", "openai-compatible", "anthropic", "google", "groq", "xai", "cohere"]>;
3
+ provider: z.ZodEnum<["openai", "openai-compatible", "anthropic", "google", "groq", "xai", "cohere", "openrouter", "litellm", "glama", "vertex", "bedrock", "local", "ollama"]>;
4
4
  model: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
5
- apiKey: z.ZodString;
5
+ apiKey: z.ZodOptional<z.ZodString>;
6
+ baseURL: z.ZodOptional<z.ZodString>;
6
7
  }, "strict", z.ZodTypeAny, {
7
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
8
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
8
9
  model: string;
9
- apiKey: string;
10
+ apiKey?: string | undefined;
11
+ baseURL?: string | undefined;
10
12
  }, {
11
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
13
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
12
14
  model: string;
13
- apiKey: string;
15
+ apiKey?: string | undefined;
16
+ baseURL?: string | undefined;
14
17
  }>, {
15
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
18
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
16
19
  model: string;
17
- apiKey: string;
20
+ apiKey?: string | undefined;
21
+ baseURL?: string | undefined;
18
22
  }, {
19
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
23
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
20
24
  model: string;
21
- apiKey: string;
25
+ apiKey?: string | undefined;
26
+ baseURL?: string | undefined;
22
27
  }>;
23
28
  export declare const PreferenceDefaultsSchema: z.ZodObject<{
24
29
  defaultAgent: z.ZodString;
@@ -32,32 +37,43 @@ export declare const PreferenceDefaultsSchema: z.ZodObject<{
32
37
  }>;
33
38
  export declare const PreferenceSetupSchema: z.ZodObject<{
34
39
  completed: z.ZodDefault<z.ZodBoolean>;
40
+ apiKeyPending: z.ZodDefault<z.ZodBoolean>;
41
+ baseURLPending: z.ZodDefault<z.ZodBoolean>;
35
42
  }, "strict", z.ZodTypeAny, {
36
43
  completed: boolean;
44
+ apiKeyPending: boolean;
45
+ baseURLPending: boolean;
37
46
  }, {
38
47
  completed?: boolean | undefined;
48
+ apiKeyPending?: boolean | undefined;
49
+ baseURLPending?: boolean | undefined;
39
50
  }>;
40
51
  export declare const GlobalPreferencesSchema: z.ZodObject<{
41
52
  llm: z.ZodEffects<z.ZodObject<{
42
- provider: z.ZodEnum<["openai", "openai-compatible", "anthropic", "google", "groq", "xai", "cohere"]>;
53
+ provider: z.ZodEnum<["openai", "openai-compatible", "anthropic", "google", "groq", "xai", "cohere", "openrouter", "litellm", "glama", "vertex", "bedrock", "local", "ollama"]>;
43
54
  model: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
44
- apiKey: z.ZodString;
55
+ apiKey: z.ZodOptional<z.ZodString>;
56
+ baseURL: z.ZodOptional<z.ZodString>;
45
57
  }, "strict", z.ZodTypeAny, {
46
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
58
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
47
59
  model: string;
48
- apiKey: string;
60
+ apiKey?: string | undefined;
61
+ baseURL?: string | undefined;
49
62
  }, {
50
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
63
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
51
64
  model: string;
52
- apiKey: string;
65
+ apiKey?: string | undefined;
66
+ baseURL?: string | undefined;
53
67
  }>, {
54
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
68
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
55
69
  model: string;
56
- apiKey: string;
70
+ apiKey?: string | undefined;
71
+ baseURL?: string | undefined;
57
72
  }, {
58
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
73
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
59
74
  model: string;
60
- apiKey: string;
75
+ apiKey?: string | undefined;
76
+ baseURL?: string | undefined;
61
77
  }>;
62
78
  defaults: z.ZodObject<{
63
79
  defaultAgent: z.ZodString;
@@ -71,16 +87,23 @@ export declare const GlobalPreferencesSchema: z.ZodObject<{
71
87
  }>;
72
88
  setup: z.ZodDefault<z.ZodObject<{
73
89
  completed: z.ZodDefault<z.ZodBoolean>;
90
+ apiKeyPending: z.ZodDefault<z.ZodBoolean>;
91
+ baseURLPending: z.ZodDefault<z.ZodBoolean>;
74
92
  }, "strict", z.ZodTypeAny, {
75
93
  completed: boolean;
94
+ apiKeyPending: boolean;
95
+ baseURLPending: boolean;
76
96
  }, {
77
97
  completed?: boolean | undefined;
98
+ apiKeyPending?: boolean | undefined;
99
+ baseURLPending?: boolean | undefined;
78
100
  }>>;
79
101
  }, "strict", z.ZodTypeAny, {
80
102
  llm: {
81
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
103
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
82
104
  model: string;
83
- apiKey: string;
105
+ apiKey?: string | undefined;
106
+ baseURL?: string | undefined;
84
107
  };
85
108
  defaults: {
86
109
  defaultAgent: string;
@@ -88,12 +111,15 @@ export declare const GlobalPreferencesSchema: z.ZodObject<{
88
111
  };
89
112
  setup: {
90
113
  completed: boolean;
114
+ apiKeyPending: boolean;
115
+ baseURLPending: boolean;
91
116
  };
92
117
  }, {
93
118
  llm: {
94
- provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
119
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
95
120
  model: string;
96
- apiKey: string;
121
+ apiKey?: string | undefined;
122
+ baseURL?: string | undefined;
97
123
  };
98
124
  defaults: {
99
125
  defaultAgent: string;
@@ -101,6 +127,8 @@ export declare const GlobalPreferencesSchema: z.ZodObject<{
101
127
  };
102
128
  setup?: {
103
129
  completed?: boolean | undefined;
130
+ apiKeyPending?: boolean | undefined;
131
+ baseURLPending?: boolean | undefined;
104
132
  } | undefined;
105
133
  }>;
106
134
  export type PreferenceLLM = z.output<typeof PreferenceLLMSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/preferences/schemas.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;EA6B1B,CAAC;AAEP,eAAO,MAAM,wBAAwB;;;;;;;;;EAYxB,CAAC;AAEd,eAAO,MAAM,qBAAqB;;;;;;EAIrB,CAAC;AAEd,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUvB,CAAC;AAGd,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACjE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC3E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/preferences/schemas.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;EA+D1B,CAAC;AAEP,eAAO,MAAM,wBAAwB;;;;;;;;;EAYxB,CAAC;AAEd,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAYrB,CAAC;AAEd,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUvB,CAAC;AAGd,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACjE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC3E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -1,5 +1,11 @@
1
1
  import { z } from "zod";
2
- import { isValidProviderModel, getSupportedModels } from "@dexto/core";
2
+ import {
3
+ isValidProviderModel,
4
+ getSupportedModels,
5
+ acceptsAnyModel,
6
+ supportsCustomModels,
7
+ supportsBaseURL
8
+ } from "@dexto/core";
3
9
  import { LLM_PROVIDERS } from "@dexto/core";
4
10
  import { NonEmptyTrimmed } from "@dexto/core";
5
11
  import { PreferenceErrorCode } from "./error-codes.js";
@@ -10,9 +16,13 @@ const PreferenceLLMSchema = z.object({
10
16
  apiKey: z.string().regex(
11
17
  /^\$[A-Z_][A-Z0-9_]*$/,
12
18
  "Must be environment variable reference (e.g., $OPENAI_API_KEY)"
13
- ).describe("Environment variable reference for API key")
19
+ ).optional().describe(
20
+ "Environment variable reference for API key (optional for local providers like Ollama)"
21
+ ),
22
+ baseURL: z.string().url("Must be a valid URL (e.g., http://localhost:11434/v1)").optional().describe("Custom base URL for providers that support it (openai-compatible, litellm)")
14
23
  }).strict().superRefine((data, ctx) => {
15
- if (!isValidProviderModel(data.provider, data.model)) {
24
+ const skipModelValidation = acceptsAnyModel(data.provider) || supportsCustomModels(data.provider);
25
+ if (!skipModelValidation && !isValidProviderModel(data.provider, data.model)) {
16
26
  const supportedModels = getSupportedModels(data.provider);
17
27
  ctx.addIssue({
18
28
  code: z.ZodIssueCode.custom,
@@ -25,13 +35,27 @@ const PreferenceLLMSchema = z.object({
25
35
  }
26
36
  });
27
37
  }
38
+ if (data.baseURL && !supportsBaseURL(data.provider)) {
39
+ ctx.addIssue({
40
+ code: z.ZodIssueCode.custom,
41
+ path: ["baseURL"],
42
+ message: `Provider '${data.provider}' does not support custom baseURL. Use 'openai-compatible' for custom endpoints.`,
43
+ params: {
44
+ code: PreferenceErrorCode.INVALID_PREFERENCE_VALUE,
45
+ scope: "preference",
46
+ type: ErrorType.USER
47
+ }
48
+ });
49
+ }
28
50
  });
29
51
  const PreferenceDefaultsSchema = z.object({
30
52
  defaultAgent: z.string().min(1).describe("Default agent name for global CLI usage (required)"),
31
53
  defaultMode: z.enum(["cli", "web", "server", "discord", "telegram", "mcp"]).default("web").describe("Default run mode when --mode flag is not specified (default: web)")
32
54
  }).strict();
33
55
  const PreferenceSetupSchema = z.object({
34
- completed: z.boolean().default(false).describe("Whether initial setup has been completed")
56
+ completed: z.boolean().default(false).describe("Whether initial setup has been completed"),
57
+ apiKeyPending: z.boolean().default(false).describe("Whether API key setup was skipped and needs to be configured later"),
58
+ baseURLPending: z.boolean().default(false).describe("Whether baseURL setup was skipped and needs to be configured later")
35
59
  }).strict();
36
60
  const GlobalPreferencesSchema = z.object({
37
61
  llm: PreferenceLLMSchema.describe("LLM configuration preferences"),
@@ -38,11 +38,10 @@ var import_fs2 = 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_types = require("./types.js");
44
42
  var import_errors = require("./errors.js");
45
43
  var import_user_registry = require("./user-registry.js");
44
+ var import_loader = require("../preferences/loader.js");
46
45
  let cachedRegistry = null;
47
46
  class LocalAgentRegistry {
48
47
  _registry = null;
@@ -175,9 +174,8 @@ class LocalAgentRegistry {
175
174
  /**
176
175
  * Install agent atomically using temp + rename pattern
177
176
  * @param agentId ID of the agent to install
178
- * @param injectPreferences Whether to inject global preferences into installed agent (default: true)
179
177
  */
180
- async installAgent(agentId, injectPreferences = true) {
178
+ async installAgent(agentId) {
181
179
  import_core.logger.info(`Installing agent: ${agentId}`);
182
180
  const registry = this.getRegistry();
183
181
  const agentData = registry.agents[agentId];
@@ -215,24 +213,6 @@ class LocalAgentRegistry {
215
213
  }
216
214
  await import_fs2.promises.rename(tempDir, targetDir);
217
215
  import_core.logger.info(`\u2713 Installed agent '${agentId}' to ${targetDir}`);
218
- if (injectPreferences) {
219
- try {
220
- const preferences = await (0, import_loader.loadGlobalPreferences)();
221
- await (0, import_writer.writePreferencesToAgent)(targetDir, preferences);
222
- import_core.logger.info(`\u2713 Applied global preferences to installed agent '${agentId}'`);
223
- } catch (error) {
224
- import_core.logger.warn(
225
- `Failed to inject preferences to '${agentId}': ${error instanceof Error ? error.message : String(error)}`
226
- );
227
- console.log(
228
- `\u26A0\uFE0F Warning: Could not apply preferences to '${agentId}' - agent will use bundled settings`
229
- );
230
- }
231
- } else {
232
- import_core.logger.info(
233
- `Skipped preference injection for '${agentId}' (injectPreferences=false)`
234
- );
235
- }
236
216
  return this.resolveMainConfig(targetDir, agentId);
237
217
  } catch (error) {
238
218
  try {
@@ -255,10 +235,9 @@ class LocalAgentRegistry {
255
235
  * @param agentId Unique identifier for the custom agent
256
236
  * @param sourcePath Absolute path to agent YAML file or directory
257
237
  * @param metadata Agent metadata (name for display, description, author, tags, main)
258
- * @param injectPreferences Whether to inject global preferences (default: true)
259
238
  * @returns Path to the installed agent's main config file
260
239
  */
261
- async installCustomAgentFromPath(agentId, sourcePath, metadata, injectPreferences = true) {
240
+ async installCustomAgentFromPath(agentId, sourcePath, metadata) {
262
241
  import_core.logger.info(`Installing custom agent '${agentId}' from ${sourcePath}`);
263
242
  this.validateCustomAgentId(agentId);
264
243
  if (!(0, import_fs.existsSync)(sourcePath)) {
@@ -332,20 +311,6 @@ class LocalAgentRegistry {
332
311
  }
333
312
  throw registryError;
334
313
  }
335
- if (injectPreferences) {
336
- try {
337
- const preferences = await (0, import_loader.loadGlobalPreferences)();
338
- await (0, import_writer.writePreferencesToAgent)(targetDir, preferences);
339
- import_core.logger.info(`\u2713 Applied global preferences to custom agent '${agentId}'`);
340
- } catch (error) {
341
- import_core.logger.warn(
342
- `Failed to inject preferences to '${agentId}': ${error instanceof Error ? error.message : String(error)}`
343
- );
344
- console.log(
345
- `\u26A0\uFE0F Warning: Could not apply preferences to '${agentId}' - agent will use default settings`
346
- );
347
- }
348
- }
349
314
  return mainConfigPath;
350
315
  } catch (error) {
351
316
  try {
@@ -369,9 +334,8 @@ class LocalAgentRegistry {
369
334
  * Handles installing agent if needed
370
335
  * @param agentId ID of the agent to resolve
371
336
  * @param autoInstall Whether to automatically install missing agents from registry (default: true)
372
- * @param injectPreferences Whether to inject preferences during auto-installation (default: true)
373
337
  */
374
- async resolveAgent(agentId, autoInstall = true, injectPreferences = true) {
338
+ async resolveAgent(agentId, autoInstall = true) {
375
339
  import_core.logger.debug(`Resolving registry agent: ${agentId}`);
376
340
  const globalAgentsDir = (0, import_path2.getDextoGlobalPath)("agents");
377
341
  const installedPath = import_path.default.resolve(globalAgentsDir, agentId);
@@ -388,7 +352,7 @@ class LocalAgentRegistry {
388
352
  if (this.hasAgent(agentId)) {
389
353
  if (autoInstall) {
390
354
  import_core.logger.info(`Installing agent '${agentId}' from registry...`);
391
- return await this.installAgent(agentId, injectPreferences);
355
+ return await this.installAgent(agentId);
392
356
  } else {
393
357
  const registry2 = this.getRegistry();
394
358
  const available2 = Object.keys(registry2.agents);
@@ -424,8 +388,8 @@ class LocalAgentRegistry {
424
388
  const defaultAgent = preferences.defaults.defaultAgent;
425
389
  return agentId !== defaultAgent;
426
390
  } catch {
427
- import_core.logger.warn("Could not load preferences, using fallback protection for default-agent");
428
- return agentId !== "default-agent";
391
+ import_core.logger.warn("Could not load preferences, using fallback protection for coding-agent");
392
+ return agentId !== "coding-agent";
429
393
  }
430
394
  }
431
395
  /**
@@ -79,15 +79,13 @@ export declare class LocalAgentRegistry implements AgentRegistry {
79
79
  /**
80
80
  * Install agent atomically using temp + rename pattern
81
81
  * @param agentId ID of the agent to install
82
- * @param injectPreferences Whether to inject global preferences into installed agent (default: true)
83
82
  */
84
- installAgent(agentId: string, injectPreferences?: boolean): Promise<string>;
83
+ installAgent(agentId: string): Promise<string>;
85
84
  /**
86
85
  * Install a custom agent from a local file path
87
86
  * @param agentId Unique identifier for the custom agent
88
87
  * @param sourcePath Absolute path to agent YAML file or directory
89
88
  * @param metadata Agent metadata (name for display, description, author, tags, main)
90
- * @param injectPreferences Whether to inject global preferences (default: true)
91
89
  * @returns Path to the installed agent's main config file
92
90
  */
93
91
  installCustomAgentFromPath(agentId: string, sourcePath: string, metadata: {
@@ -96,16 +94,15 @@ export declare class LocalAgentRegistry implements AgentRegistry {
96
94
  author: string;
97
95
  tags: string[];
98
96
  main?: string;
99
- }, injectPreferences?: boolean): Promise<string>;
97
+ }): Promise<string>;
100
98
  /**
101
99
  * Resolve a registry agent ID to a config path
102
100
  * NOTE: Only handles registry IDs, not file paths (routing done in loadAgentConfig)
103
101
  * Handles installing agent if needed
104
102
  * @param agentId ID of the agent to resolve
105
103
  * @param autoInstall Whether to automatically install missing agents from registry (default: true)
106
- * @param injectPreferences Whether to inject preferences during auto-installation (default: true)
107
104
  */
108
- resolveAgent(agentId: string, autoInstall?: boolean, injectPreferences?: boolean): Promise<string>;
105
+ resolveAgent(agentId: string, autoInstall?: boolean): Promise<string>;
109
106
  /**
110
107
  * Get list of currently installed agents
111
108
  */
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,QAAQ,EAER,aAAa,EACb,kBAAkB,EAErB,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACpD,OAAO,CAAC,SAAS,CAAyB;IAE1C;;OAEG;IACH,WAAW,IAAI,QAAQ;IAOvB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAyCpB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKlC;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAKxD;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAgC7B;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IA0C5D;;;;OAIG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,GAAE,OAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAqGvF;;;;;;;OAOG;IACG,0BAA0B,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,EACD,iBAAiB,GAAE,OAAc,GAClC,OAAO,CAAC,MAAM,CAAC;IAqKlB;;;;;;;OAOG;IACG,YAAY,CACd,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,OAAc,EAC3B,iBAAiB,GAAE,OAAc,GAClC,OAAO,CAAC,MAAM,CAAC;IAsClB;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAsB7C;;OAEG;YACW,sBAAsB;IAYpC;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CA8C/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,CAKrD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAY9E"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,QAAQ,EAER,aAAa,EACb,kBAAkB,EAErB,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACpD,OAAO,CAAC,SAAS,CAAyB;IAE1C;;OAEG;IACH,WAAW,IAAI,QAAQ;IAOvB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAyCpB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKlC;;OAEG;IACH,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAKxD;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAgC7B;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IA0C5D;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgFpD;;;;;;OAMG;IACG,0BAA0B,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,GACF,OAAO,CAAC,MAAM,CAAC;IAqJlB;;;;;;OAMG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,OAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAsCjF;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAsB7C;;OAEG;YACW,sBAAsB;IAYpC;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CA8C/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,CAKrD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAY9E"}
@@ -3,8 +3,6 @@ import { promises as fs } from "fs";
3
3
  import path from "path";
4
4
  import { logger } from "@dexto/core";
5
5
  import { resolveBundledScript, getDextoGlobalPath, copyDirectory } from "../utils/path.js";
6
- import { loadGlobalPreferences } from "../preferences/loader.js";
7
- import { writePreferencesToAgent } from "../writer.js";
8
6
  import {
9
7
  RegistrySchema,
10
8
  normalizeRegistryJson
@@ -16,6 +14,7 @@ import {
16
14
  removeAgentFromUserRegistry,
17
15
  addAgentToUserRegistry
18
16
  } from "./user-registry.js";
17
+ import { loadGlobalPreferences } from "../preferences/loader.js";
19
18
  let cachedRegistry = null;
20
19
  class LocalAgentRegistry {
21
20
  _registry = null;
@@ -148,9 +147,8 @@ class LocalAgentRegistry {
148
147
  /**
149
148
  * Install agent atomically using temp + rename pattern
150
149
  * @param agentId ID of the agent to install
151
- * @param injectPreferences Whether to inject global preferences into installed agent (default: true)
152
150
  */
153
- async installAgent(agentId, injectPreferences = true) {
151
+ async installAgent(agentId) {
154
152
  logger.info(`Installing agent: ${agentId}`);
155
153
  const registry = this.getRegistry();
156
154
  const agentData = registry.agents[agentId];
@@ -188,24 +186,6 @@ class LocalAgentRegistry {
188
186
  }
189
187
  await fs.rename(tempDir, targetDir);
190
188
  logger.info(`\u2713 Installed agent '${agentId}' to ${targetDir}`);
191
- if (injectPreferences) {
192
- try {
193
- const preferences = await loadGlobalPreferences();
194
- await writePreferencesToAgent(targetDir, preferences);
195
- logger.info(`\u2713 Applied global preferences to installed agent '${agentId}'`);
196
- } catch (error) {
197
- logger.warn(
198
- `Failed to inject preferences to '${agentId}': ${error instanceof Error ? error.message : String(error)}`
199
- );
200
- console.log(
201
- `\u26A0\uFE0F Warning: Could not apply preferences to '${agentId}' - agent will use bundled settings`
202
- );
203
- }
204
- } else {
205
- logger.info(
206
- `Skipped preference injection for '${agentId}' (injectPreferences=false)`
207
- );
208
- }
209
189
  return this.resolveMainConfig(targetDir, agentId);
210
190
  } catch (error) {
211
191
  try {
@@ -228,10 +208,9 @@ class LocalAgentRegistry {
228
208
  * @param agentId Unique identifier for the custom agent
229
209
  * @param sourcePath Absolute path to agent YAML file or directory
230
210
  * @param metadata Agent metadata (name for display, description, author, tags, main)
231
- * @param injectPreferences Whether to inject global preferences (default: true)
232
211
  * @returns Path to the installed agent's main config file
233
212
  */
234
- async installCustomAgentFromPath(agentId, sourcePath, metadata, injectPreferences = true) {
213
+ async installCustomAgentFromPath(agentId, sourcePath, metadata) {
235
214
  logger.info(`Installing custom agent '${agentId}' from ${sourcePath}`);
236
215
  this.validateCustomAgentId(agentId);
237
216
  if (!existsSync(sourcePath)) {
@@ -305,20 +284,6 @@ class LocalAgentRegistry {
305
284
  }
306
285
  throw registryError;
307
286
  }
308
- if (injectPreferences) {
309
- try {
310
- const preferences = await loadGlobalPreferences();
311
- await writePreferencesToAgent(targetDir, preferences);
312
- logger.info(`\u2713 Applied global preferences to custom agent '${agentId}'`);
313
- } catch (error) {
314
- logger.warn(
315
- `Failed to inject preferences to '${agentId}': ${error instanceof Error ? error.message : String(error)}`
316
- );
317
- console.log(
318
- `\u26A0\uFE0F Warning: Could not apply preferences to '${agentId}' - agent will use default settings`
319
- );
320
- }
321
- }
322
287
  return mainConfigPath;
323
288
  } catch (error) {
324
289
  try {
@@ -342,9 +307,8 @@ class LocalAgentRegistry {
342
307
  * Handles installing agent if needed
343
308
  * @param agentId ID of the agent to resolve
344
309
  * @param autoInstall Whether to automatically install missing agents from registry (default: true)
345
- * @param injectPreferences Whether to inject preferences during auto-installation (default: true)
346
310
  */
347
- async resolveAgent(agentId, autoInstall = true, injectPreferences = true) {
311
+ async resolveAgent(agentId, autoInstall = true) {
348
312
  logger.debug(`Resolving registry agent: ${agentId}`);
349
313
  const globalAgentsDir = getDextoGlobalPath("agents");
350
314
  const installedPath = path.resolve(globalAgentsDir, agentId);
@@ -361,7 +325,7 @@ class LocalAgentRegistry {
361
325
  if (this.hasAgent(agentId)) {
362
326
  if (autoInstall) {
363
327
  logger.info(`Installing agent '${agentId}' from registry...`);
364
- return await this.installAgent(agentId, injectPreferences);
328
+ return await this.installAgent(agentId);
365
329
  } else {
366
330
  const registry2 = this.getRegistry();
367
331
  const available2 = Object.keys(registry2.agents);
@@ -397,8 +361,8 @@ class LocalAgentRegistry {
397
361
  const defaultAgent = preferences.defaults.defaultAgent;
398
362
  return agentId !== defaultAgent;
399
363
  } catch {
400
- logger.warn("Could not load preferences, using fallback protection for default-agent");
401
- return agentId !== "default-agent";
364
+ logger.warn("Could not load preferences, using fallback protection for coding-agent");
365
+ return agentId !== "coding-agent";
402
366
  }
403
367
  }
404
368
  /**