@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.
- package/dist/AgentFactory.cjs +1 -2
- package/dist/AgentFactory.d.ts +1 -1
- package/dist/AgentFactory.d.ts.map +1 -1
- package/dist/AgentFactory.js +1 -2
- package/dist/config/config-enrichment.cjs +1 -1
- package/dist/config/config-enrichment.d.ts +1 -1
- package/dist/config/config-enrichment.js +1 -1
- package/dist/config/errors.cjs +2 -2
- package/dist/config/errors.js +2 -2
- package/dist/index.cjs +69 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -2
- package/dist/installation.cjs +0 -13
- package/dist/installation.d.ts +0 -2
- package/dist/installation.d.ts.map +1 -1
- package/dist/installation.js +0 -13
- package/dist/models/custom-models.cjs +43 -2
- package/dist/models/custom-models.d.ts +49 -6
- package/dist/models/custom-models.d.ts.map +1 -1
- package/dist/models/custom-models.js +42 -2
- package/dist/models/index.cjs +89 -0
- package/dist/models/index.d.ts +11 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +68 -0
- package/dist/models/path-resolver.cjs +154 -0
- package/dist/models/path-resolver.d.ts +77 -0
- package/dist/models/path-resolver.d.ts.map +1 -0
- package/dist/models/path-resolver.js +108 -0
- package/dist/models/state-manager.cjs +220 -0
- package/dist/models/state-manager.d.ts +138 -0
- package/dist/models/state-manager.d.ts.map +1 -0
- package/dist/models/state-manager.js +184 -0
- package/dist/preferences/error-codes.cjs +2 -0
- package/dist/preferences/error-codes.d.ts +3 -1
- package/dist/preferences/error-codes.d.ts.map +1 -1
- package/dist/preferences/error-codes.js +2 -0
- package/dist/preferences/index.d.ts +1 -1
- package/dist/preferences/index.d.ts.map +1 -1
- package/dist/preferences/loader.cjs +32 -6
- package/dist/preferences/loader.d.ts +23 -4
- package/dist/preferences/loader.d.ts.map +1 -1
- package/dist/preferences/loader.js +32 -6
- package/dist/preferences/schemas.cjs +21 -3
- package/dist/preferences/schemas.d.ts +52 -24
- package/dist/preferences/schemas.d.ts.map +1 -1
- package/dist/preferences/schemas.js +28 -4
- package/dist/registry/registry.cjs +7 -43
- package/dist/registry/registry.d.ts +3 -6
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +7 -43
- package/dist/registry/types.d.ts +2 -4
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/resolver.cjs +20 -20
- package/dist/resolver.d.ts +1 -2
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +20 -20
- package/dist/utils/api-key-resolver.cjs +19 -1
- package/dist/utils/api-key-resolver.d.ts.map +1 -1
- package/dist/utils/api-key-resolver.js +19 -1
- package/dist/utils/api-key-store.cjs +46 -0
- package/dist/utils/api-key-store.d.ts +27 -0
- package/dist/utils/api-key-store.d.ts.map +1 -1
- package/dist/utils/api-key-store.js +44 -0
- package/dist/utils/env-file.cjs +20 -68
- package/dist/utils/env-file.d.ts +2 -1
- package/dist/utils/env-file.d.ts.map +1 -1
- package/dist/utils/env-file.js +20 -68
- package/dist/writer.cjs +20 -2
- package/dist/writer.d.ts +1 -0
- package/dist/writer.d.ts.map +1 -1
- package/dist/writer.js +20 -2
- package/package.json +2 -2
|
@@ -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
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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;
|
|
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 {
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
428
|
-
return agentId !== "
|
|
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
|
|
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
|
-
}
|
|
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
|
|
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":"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
401
|
-
return agentId !== "
|
|
364
|
+
logger.warn("Could not load preferences, using fallback protection for coding-agent");
|
|
365
|
+
return agentId !== "coding-agent";
|
|
402
366
|
}
|
|
403
367
|
}
|
|
404
368
|
/**
|