@dexto/agent-management 1.5.6 → 1.5.8
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/config/config-enrichment.cjs +72 -21
- package/dist/config/config-enrichment.d.ts +10 -2
- package/dist/config/config-enrichment.d.ts.map +1 -1
- package/dist/config/config-enrichment.js +76 -21
- package/dist/config/discover-prompts.cjs +1 -1
- package/dist/config/discover-prompts.d.ts +11 -11
- package/dist/config/discover-prompts.d.ts.map +1 -1
- package/dist/config/discover-prompts.js +1 -1
- package/dist/config/loader.cjs +31 -13
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +31 -13
- package/dist/index.cjs +76 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -0
- package/dist/models/custom-models.cjs +2 -1
- package/dist/models/custom-models.d.ts +7 -6
- package/dist/models/custom-models.d.ts.map +1 -1
- package/dist/models/custom-models.js +2 -1
- package/dist/plugins/discover-plugins.cjs +176 -0
- package/dist/plugins/discover-plugins.d.ts +39 -0
- package/dist/plugins/discover-plugins.d.ts.map +1 -0
- package/dist/plugins/discover-plugins.js +140 -0
- package/dist/plugins/discover-skills.cjs +93 -0
- package/dist/plugins/discover-skills.d.ts +49 -0
- package/dist/plugins/discover-skills.d.ts.map +1 -0
- package/dist/plugins/discover-skills.js +58 -0
- package/dist/plugins/error-codes.cjs +47 -0
- package/dist/plugins/error-codes.d.ts +24 -0
- package/dist/plugins/error-codes.d.ts.map +1 -0
- package/dist/plugins/error-codes.js +23 -0
- package/dist/plugins/errors.cjs +197 -0
- package/dist/plugins/errors.d.ts +68 -0
- package/dist/plugins/errors.d.ts.map +1 -0
- package/dist/plugins/errors.js +173 -0
- package/dist/plugins/index.cjs +144 -0
- package/dist/plugins/index.d.ts +23 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +115 -0
- package/dist/plugins/install-plugin.cjs +211 -0
- package/dist/plugins/install-plugin.d.ts +47 -0
- package/dist/plugins/install-plugin.d.ts.map +1 -0
- package/dist/plugins/install-plugin.js +173 -0
- package/dist/plugins/list-plugins.cjs +134 -0
- package/dist/plugins/list-plugins.d.ts +26 -0
- package/dist/plugins/list-plugins.d.ts.map +1 -0
- package/dist/plugins/list-plugins.js +99 -0
- package/dist/plugins/load-plugin.cjs +197 -0
- package/dist/plugins/load-plugin.d.ts +20 -0
- package/dist/plugins/load-plugin.d.ts.map +1 -0
- package/dist/plugins/load-plugin.js +163 -0
- package/dist/plugins/marketplace/error-codes.cjs +45 -0
- package/dist/plugins/marketplace/error-codes.d.ts +21 -0
- package/dist/plugins/marketplace/error-codes.d.ts.map +1 -0
- package/dist/plugins/marketplace/error-codes.js +21 -0
- package/dist/plugins/marketplace/errors.cjs +188 -0
- package/dist/plugins/marketplace/errors.d.ts +64 -0
- package/dist/plugins/marketplace/errors.d.ts.map +1 -0
- package/dist/plugins/marketplace/errors.js +164 -0
- package/dist/plugins/marketplace/index.cjs +95 -0
- package/dist/plugins/marketplace/index.d.ts +14 -0
- package/dist/plugins/marketplace/index.d.ts.map +1 -0
- package/dist/plugins/marketplace/index.js +74 -0
- package/dist/plugins/marketplace/install-from-marketplace.cjs +152 -0
- package/dist/plugins/marketplace/install-from-marketplace.d.ts +25 -0
- package/dist/plugins/marketplace/install-from-marketplace.d.ts.map +1 -0
- package/dist/plugins/marketplace/install-from-marketplace.js +120 -0
- package/dist/plugins/marketplace/operations.cjs +374 -0
- package/dist/plugins/marketplace/operations.d.ts +43 -0
- package/dist/plugins/marketplace/operations.d.ts.map +1 -0
- package/dist/plugins/marketplace/operations.js +339 -0
- package/dist/plugins/marketplace/registry.cjs +166 -0
- package/dist/plugins/marketplace/registry.d.ts +72 -0
- package/dist/plugins/marketplace/registry.d.ts.map +1 -0
- package/dist/plugins/marketplace/registry.js +119 -0
- package/dist/plugins/marketplace/schemas.cjs +79 -0
- package/dist/plugins/marketplace/schemas.d.ts +260 -0
- package/dist/plugins/marketplace/schemas.d.ts.map +1 -0
- package/dist/plugins/marketplace/schemas.js +49 -0
- package/dist/plugins/marketplace/types.cjs +16 -0
- package/dist/plugins/marketplace/types.d.ts +156 -0
- package/dist/plugins/marketplace/types.d.ts.map +1 -0
- package/dist/plugins/marketplace/types.js +0 -0
- package/dist/plugins/schemas.cjs +74 -0
- package/dist/plugins/schemas.d.ts +262 -0
- package/dist/plugins/schemas.d.ts.map +1 -0
- package/dist/plugins/schemas.js +46 -0
- package/dist/plugins/types.cjs +16 -0
- package/dist/plugins/types.d.ts +186 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +0 -0
- package/dist/plugins/uninstall-plugin.cjs +133 -0
- package/dist/plugins/uninstall-plugin.d.ts +24 -0
- package/dist/plugins/uninstall-plugin.d.ts.map +1 -0
- package/dist/plugins/uninstall-plugin.js +99 -0
- package/dist/plugins/validate-plugin.cjs +180 -0
- package/dist/plugins/validate-plugin.d.ts +53 -0
- package/dist/plugins/validate-plugin.d.ts.map +1 -0
- package/dist/plugins/validate-plugin.js +145 -0
- package/dist/preferences/errors.cjs +11 -0
- package/dist/preferences/errors.d.ts +1 -0
- package/dist/preferences/errors.d.ts.map +1 -1
- package/dist/preferences/errors.js +11 -0
- package/dist/preferences/loader.cjs +119 -6
- package/dist/preferences/loader.d.ts +21 -1
- package/dist/preferences/loader.d.ts.map +1 -1
- package/dist/preferences/loader.js +102 -1
- package/dist/preferences/schemas.cjs +12 -0
- package/dist/preferences/schemas.d.ts +38 -12
- package/dist/preferences/schemas.d.ts.map +1 -1
- package/dist/preferences/schemas.js +10 -0
- package/dist/runtime/AgentRuntime.cjs +1 -2
- package/dist/runtime/AgentRuntime.d.ts.map +1 -1
- package/dist/runtime/AgentRuntime.js +1 -2
- package/dist/tool-provider/llm-resolution.cjs +74 -0
- package/dist/tool-provider/llm-resolution.d.ts +51 -0
- package/dist/tool-provider/llm-resolution.d.ts.map +1 -0
- package/dist/tool-provider/llm-resolution.js +50 -0
- package/dist/tool-provider/runtime-service.cjs +246 -34
- package/dist/tool-provider/runtime-service.d.ts +34 -2
- package/dist/tool-provider/runtime-service.d.ts.map +1 -1
- package/dist/tool-provider/runtime-service.js +236 -34
- package/dist/tool-provider/tool-provider.cjs +154 -1
- package/dist/tool-provider/tool-provider.d.ts +7 -1
- package/dist/tool-provider/tool-provider.d.ts.map +1 -1
- package/dist/tool-provider/tool-provider.js +161 -1
- package/dist/tool-provider/types.d.ts +2 -0
- package/dist/tool-provider/types.d.ts.map +1 -1
- package/dist/utils/api-key-resolver.cjs +5 -2
- package/dist/utils/api-key-resolver.d.ts.map +1 -1
- package/dist/utils/api-key-resolver.js +5 -2
- package/dist/utils/dexto-auth.cjs +83 -0
- package/dist/utils/dexto-auth.d.ts +23 -0
- package/dist/utils/dexto-auth.d.ts.map +1 -0
- package/dist/utils/dexto-auth.js +57 -0
- package/dist/utils/feature-flags.cjs +32 -0
- package/dist/utils/feature-flags.d.ts +21 -0
- package/dist/utils/feature-flags.d.ts.map +1 -0
- package/dist/utils/feature-flags.js +8 -0
- package/package.json +3 -2
|
@@ -0,0 +1,74 @@
|
|
|
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 llm_resolution_exports = {};
|
|
20
|
+
__export(llm_resolution_exports, {
|
|
21
|
+
resolveSubAgentLLM: () => resolveSubAgentLLM
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(llm_resolution_exports);
|
|
24
|
+
var import_core = require("@dexto/core");
|
|
25
|
+
function resolveSubAgentLLM(options) {
|
|
26
|
+
const { subAgentLLM, parentLLM, subAgentId } = options;
|
|
27
|
+
const agentLabel = subAgentId ? `'${subAgentId}'` : "sub-agent";
|
|
28
|
+
const subAgentProvider = subAgentLLM.provider;
|
|
29
|
+
const subAgentModel = subAgentLLM.model;
|
|
30
|
+
const parentProvider = parentLLM.provider;
|
|
31
|
+
if ((0, import_core.hasAllRegistryModelsSupport)(parentProvider)) {
|
|
32
|
+
try {
|
|
33
|
+
const transformedModel = (0, import_core.transformModelNameForProvider)(
|
|
34
|
+
subAgentModel,
|
|
35
|
+
subAgentProvider,
|
|
36
|
+
parentProvider
|
|
37
|
+
);
|
|
38
|
+
return {
|
|
39
|
+
llm: {
|
|
40
|
+
...subAgentLLM,
|
|
41
|
+
provider: parentProvider,
|
|
42
|
+
model: transformedModel,
|
|
43
|
+
apiKey: parentLLM.apiKey,
|
|
44
|
+
baseURL: parentLLM.baseURL
|
|
45
|
+
},
|
|
46
|
+
resolution: "gateway-transform",
|
|
47
|
+
reason: `${agentLabel} using ${parentProvider} gateway with model ${transformedModel} (transformed from ${subAgentProvider}/${subAgentModel})`
|
|
48
|
+
};
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (parentProvider === subAgentProvider) {
|
|
53
|
+
return {
|
|
54
|
+
llm: {
|
|
55
|
+
...subAgentLLM,
|
|
56
|
+
apiKey: parentLLM.apiKey,
|
|
57
|
+
// Use parent's credentials
|
|
58
|
+
baseURL: parentLLM.baseURL
|
|
59
|
+
// Inherit custom endpoint (e.g., Azure OpenAI)
|
|
60
|
+
},
|
|
61
|
+
resolution: "same-provider",
|
|
62
|
+
reason: `${agentLabel} using ${subAgentProvider}/${subAgentModel} with parent's credentials`
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
llm: parentLLM,
|
|
67
|
+
resolution: "parent-fallback",
|
|
68
|
+
reason: `${agentLabel} cannot use ${subAgentProvider}/${subAgentModel} with parent's ${parentProvider} provider. Falling back to parent's LLM config. Tip: Use 'dexto login' for Dexto Nova Credits which supports all models.`
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
resolveSubAgentLLM
|
|
74
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sub-agent LLM resolution logic
|
|
3
|
+
*
|
|
4
|
+
* When a parent agent spawns a sub-agent (e.g., coding-agent spawns explore-agent),
|
|
5
|
+
* this module determines which LLM configuration the sub-agent should use.
|
|
6
|
+
*
|
|
7
|
+
* Resolution priority:
|
|
8
|
+
* 1. If parent's provider can serve sub-agent's model (dexto-nova/openrouter/same provider)
|
|
9
|
+
* → Use parent's provider + sub-agent's model (transformed if needed)
|
|
10
|
+
* 2. If incompatible providers
|
|
11
|
+
* → Fall back to parent's full LLM config (with warning)
|
|
12
|
+
*
|
|
13
|
+
* Future enhancement (when .local.yml is implemented):
|
|
14
|
+
* 0. Check sub-agent's .local.yml for LLM override (highest priority)
|
|
15
|
+
*/
|
|
16
|
+
import type { LLMConfig } from '@dexto/core';
|
|
17
|
+
/**
|
|
18
|
+
* Result of resolving a sub-agent's LLM configuration
|
|
19
|
+
*/
|
|
20
|
+
export interface SubAgentLLMResolution {
|
|
21
|
+
/** The resolved LLM configuration to use */
|
|
22
|
+
llm: LLMConfig;
|
|
23
|
+
/** How the resolution was determined */
|
|
24
|
+
resolution: 'gateway-transform' | 'same-provider' | 'parent-fallback';
|
|
25
|
+
/** Human-readable explanation for debugging */
|
|
26
|
+
reason: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ResolveSubAgentLLMOptions {
|
|
29
|
+
/** The sub-agent's bundled LLM configuration */
|
|
30
|
+
subAgentLLM: LLMConfig;
|
|
31
|
+
/** The parent agent's LLM configuration (already has preferences applied) */
|
|
32
|
+
parentLLM: LLMConfig;
|
|
33
|
+
/** Sub-agent ID for logging purposes */
|
|
34
|
+
subAgentId?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolves which LLM configuration a sub-agent should use.
|
|
38
|
+
*
|
|
39
|
+
* The goal is to use the sub-agent's intended model (e.g., Haiku for explore-agent)
|
|
40
|
+
* when possible, while leveraging the parent's provider/credentials.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Parent uses dexto-nova, sub-agent wants anthropic/haiku
|
|
44
|
+
* resolveSubAgentLLM({
|
|
45
|
+
* subAgentLLM: { provider: 'anthropic', model: 'claude-haiku-4-5-20251001', apiKey: '$ANTHROPIC_API_KEY' },
|
|
46
|
+
* parentLLM: { provider: 'dexto-nova', model: 'anthropic/claude-sonnet-4', apiKey: '$DEXTO_API_KEY' }
|
|
47
|
+
* })
|
|
48
|
+
* // Returns: { provider: 'dexto-nova', model: 'anthropic/claude-haiku-4.5', apiKey: '$DEXTO_API_KEY' }
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveSubAgentLLM(options: ResolveSubAgentLLMOptions): SubAgentLLMResolution;
|
|
51
|
+
//# sourceMappingURL=llm-resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-resolution.d.ts","sourceRoot":"","sources":["../../src/tool-provider/llm-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,4CAA4C;IAC5C,GAAG,EAAE,SAAS,CAAC;IACf,wCAAwC;IACxC,UAAU,EACJ,mBAAmB,GACnB,eAAe,GACf,iBAAiB,CAAC;IACxB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACtC,gDAAgD;IAChD,WAAW,EAAE,SAAS,CAAC;IACvB,6EAA6E;IAC7E,SAAS,EAAE,SAAS,CAAC;IACrB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,qBAAqB,CAmE5F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { hasAllRegistryModelsSupport, transformModelNameForProvider } from "@dexto/core";
|
|
2
|
+
function resolveSubAgentLLM(options) {
|
|
3
|
+
const { subAgentLLM, parentLLM, subAgentId } = options;
|
|
4
|
+
const agentLabel = subAgentId ? `'${subAgentId}'` : "sub-agent";
|
|
5
|
+
const subAgentProvider = subAgentLLM.provider;
|
|
6
|
+
const subAgentModel = subAgentLLM.model;
|
|
7
|
+
const parentProvider = parentLLM.provider;
|
|
8
|
+
if (hasAllRegistryModelsSupport(parentProvider)) {
|
|
9
|
+
try {
|
|
10
|
+
const transformedModel = transformModelNameForProvider(
|
|
11
|
+
subAgentModel,
|
|
12
|
+
subAgentProvider,
|
|
13
|
+
parentProvider
|
|
14
|
+
);
|
|
15
|
+
return {
|
|
16
|
+
llm: {
|
|
17
|
+
...subAgentLLM,
|
|
18
|
+
provider: parentProvider,
|
|
19
|
+
model: transformedModel,
|
|
20
|
+
apiKey: parentLLM.apiKey,
|
|
21
|
+
baseURL: parentLLM.baseURL
|
|
22
|
+
},
|
|
23
|
+
resolution: "gateway-transform",
|
|
24
|
+
reason: `${agentLabel} using ${parentProvider} gateway with model ${transformedModel} (transformed from ${subAgentProvider}/${subAgentModel})`
|
|
25
|
+
};
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (parentProvider === subAgentProvider) {
|
|
30
|
+
return {
|
|
31
|
+
llm: {
|
|
32
|
+
...subAgentLLM,
|
|
33
|
+
apiKey: parentLLM.apiKey,
|
|
34
|
+
// Use parent's credentials
|
|
35
|
+
baseURL: parentLLM.baseURL
|
|
36
|
+
// Inherit custom endpoint (e.g., Azure OpenAI)
|
|
37
|
+
},
|
|
38
|
+
resolution: "same-provider",
|
|
39
|
+
reason: `${agentLabel} using ${subAgentProvider}/${subAgentModel} with parent's credentials`
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
llm: parentLLM,
|
|
44
|
+
resolution: "parent-fallback",
|
|
45
|
+
reason: `${agentLabel} cannot use ${subAgentProvider}/${subAgentModel} with parent's ${parentProvider} provider. Falling back to parent's LLM config. Tip: Use 'dexto login' for Dexto Nova Credits which supports all models.`
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
resolveSubAgentLLM
|
|
50
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,22 +17,66 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
var runtime_service_exports = {};
|
|
20
30
|
__export(runtime_service_exports, {
|
|
21
31
|
RuntimeService: () => RuntimeService
|
|
22
32
|
});
|
|
23
33
|
module.exports = __toCommonJS(runtime_service_exports);
|
|
34
|
+
var import_core = require("@dexto/core");
|
|
24
35
|
var import_AgentRuntime = require("../runtime/AgentRuntime.js");
|
|
25
36
|
var import_approval_delegation = require("../runtime/approval-delegation.js");
|
|
26
37
|
var import_loader = require("../config/loader.js");
|
|
27
38
|
var import_registry = require("../registry/registry.js");
|
|
39
|
+
var import_types = require("../registry/types.js");
|
|
40
|
+
var import_path = require("../utils/path.js");
|
|
41
|
+
var path = __toESM(require("path"), 1);
|
|
42
|
+
var import_llm_resolution = require("./llm-resolution.js");
|
|
28
43
|
class RuntimeService {
|
|
29
44
|
runtime;
|
|
30
45
|
parentId;
|
|
31
46
|
parentAgent;
|
|
32
47
|
config;
|
|
33
48
|
logger;
|
|
49
|
+
resolveBundledAgentConfig(agentId) {
|
|
50
|
+
const baseDir = "agents";
|
|
51
|
+
const normalizedPath = path.relative(baseDir, path.join(baseDir, agentId));
|
|
52
|
+
if (normalizedPath.startsWith("..") || path.isAbsolute(normalizedPath)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const candidates = [
|
|
56
|
+
`agents/${agentId}/${agentId}.yml`,
|
|
57
|
+
`agents/${agentId}/${agentId}.yaml`,
|
|
58
|
+
`agents/${agentId}.yml`,
|
|
59
|
+
`agents/${agentId}.yaml`
|
|
60
|
+
];
|
|
61
|
+
for (const candidate of candidates) {
|
|
62
|
+
try {
|
|
63
|
+
return (0, import_path.resolveBundledScript)(candidate);
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
createFallbackRegistryEntry(agentId) {
|
|
70
|
+
return {
|
|
71
|
+
id: agentId,
|
|
72
|
+
name: (0, import_types.deriveDisplayName)(agentId),
|
|
73
|
+
description: "Agent specified in config (registry entry not found)",
|
|
74
|
+
author: "unknown",
|
|
75
|
+
tags: [],
|
|
76
|
+
source: agentId,
|
|
77
|
+
type: "custom"
|
|
78
|
+
};
|
|
79
|
+
}
|
|
34
80
|
constructor(parentAgent, config, logger) {
|
|
35
81
|
this.parentAgent = parentAgent;
|
|
36
82
|
this.config = config;
|
|
@@ -69,6 +115,7 @@ class RuntimeService {
|
|
|
69
115
|
* @param input.task - Short task description (for logging/UI)
|
|
70
116
|
* @param input.instructions - Full prompt sent to sub-agent
|
|
71
117
|
* @param input.agentId - Optional agent ID from registry
|
|
118
|
+
* @param input.autoApprove - Optional override for auto-approve (used by fork skills)
|
|
72
119
|
* @param input.timeout - Optional task timeout in milliseconds
|
|
73
120
|
* @param input.toolCallId - Optional tool call ID for progress events
|
|
74
121
|
* @param input.sessionId - Optional session ID for progress events
|
|
@@ -95,10 +142,7 @@ class RuntimeService {
|
|
|
95
142
|
}
|
|
96
143
|
}
|
|
97
144
|
const timeout = input.timeout ?? this.config.defaultTimeout;
|
|
98
|
-
|
|
99
|
-
if (input.agentId && this.config.autoApproveAgents) {
|
|
100
|
-
autoApprove = this.config.autoApproveAgents.includes(input.agentId);
|
|
101
|
-
}
|
|
145
|
+
const autoApprove = input.autoApprove !== void 0 ? input.autoApprove : !!(input.agentId && this.config.autoApproveAgents?.includes(input.agentId));
|
|
102
146
|
const result = await this.trySpawnWithFallback(
|
|
103
147
|
input,
|
|
104
148
|
timeout,
|
|
@@ -108,6 +152,36 @@ class RuntimeService {
|
|
|
108
152
|
);
|
|
109
153
|
return result;
|
|
110
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Fork execution to an isolated subagent.
|
|
157
|
+
* Implements TaskForker interface for use by invoke_skill when context: fork is set.
|
|
158
|
+
*
|
|
159
|
+
* @param options.task - Short description for UI/logs
|
|
160
|
+
* @param options.instructions - Full instructions for the subagent
|
|
161
|
+
* @param options.agentId - Optional agent ID from registry to use for execution
|
|
162
|
+
* @param options.autoApprove - Auto-approve tool calls (default: true for fork skills)
|
|
163
|
+
* @param options.toolCallId - Optional tool call ID for progress events
|
|
164
|
+
* @param options.sessionId - Optional session ID for progress events
|
|
165
|
+
*/
|
|
166
|
+
async fork(options) {
|
|
167
|
+
const spawnOptions = {
|
|
168
|
+
task: options.task,
|
|
169
|
+
instructions: options.instructions
|
|
170
|
+
};
|
|
171
|
+
if (options.agentId) {
|
|
172
|
+
spawnOptions.agentId = options.agentId;
|
|
173
|
+
}
|
|
174
|
+
if (options.autoApprove !== void 0) {
|
|
175
|
+
spawnOptions.autoApprove = options.autoApprove;
|
|
176
|
+
}
|
|
177
|
+
if (options.toolCallId) {
|
|
178
|
+
spawnOptions.toolCallId = options.toolCallId;
|
|
179
|
+
}
|
|
180
|
+
if (options.sessionId) {
|
|
181
|
+
spawnOptions.sessionId = options.sessionId;
|
|
182
|
+
}
|
|
183
|
+
return this.spawnAndExecute(spawnOptions);
|
|
184
|
+
}
|
|
111
185
|
/**
|
|
112
186
|
* Set up progress event emission for a sub-agent.
|
|
113
187
|
* Subscribes to llm:tool-call and llm:response events and emits service:event with progress data.
|
|
@@ -183,12 +257,25 @@ class RuntimeService {
|
|
|
183
257
|
subAgentBus.off("llm:response", responseHandler);
|
|
184
258
|
};
|
|
185
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Check if an error is LLM-related (API errors, credit issues, model not found, etc.)
|
|
262
|
+
*/
|
|
263
|
+
isLLMError(error) {
|
|
264
|
+
if (error instanceof import_core.DextoRuntimeError) {
|
|
265
|
+
if (error.scope === "llm") return true;
|
|
266
|
+
if (error.type === import_core.ErrorType.PAYMENT_REQUIRED || error.type === import_core.ErrorType.FORBIDDEN) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
271
|
+
return msg.includes("model") || msg.includes("provider") || msg.includes("rate limit") || msg.includes("quota");
|
|
272
|
+
}
|
|
186
273
|
/**
|
|
187
274
|
* Try to spawn agent, falling back to parent's LLM config if the sub-agent's config fails
|
|
188
275
|
*/
|
|
189
276
|
async trySpawnWithFallback(input, timeout, autoApprove, toolCallId, sessionId) {
|
|
190
277
|
let spawnedAgentId;
|
|
191
|
-
let
|
|
278
|
+
let llmMode = "subagent";
|
|
192
279
|
let cleanupProgressTracking;
|
|
193
280
|
try {
|
|
194
281
|
const buildOptions = {};
|
|
@@ -198,7 +285,7 @@ class RuntimeService {
|
|
|
198
285
|
if (autoApprove) {
|
|
199
286
|
buildOptions.autoApprove = autoApprove;
|
|
200
287
|
}
|
|
201
|
-
let subAgentConfig = await this.buildSubAgentConfig(buildOptions);
|
|
288
|
+
let subAgentConfig = await this.buildSubAgentConfig(buildOptions, sessionId);
|
|
202
289
|
let handle;
|
|
203
290
|
try {
|
|
204
291
|
handle = await this.runtime.spawnAgent({
|
|
@@ -224,15 +311,15 @@ class RuntimeService {
|
|
|
224
311
|
});
|
|
225
312
|
spawnedAgentId = handle.agentId;
|
|
226
313
|
} catch (spawnError) {
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
314
|
+
const isLlmError = this.isLLMError(spawnError);
|
|
315
|
+
if (isLlmError && input.agentId && llmMode === "subagent") {
|
|
316
|
+
const errorMsg = spawnError instanceof Error ? spawnError.message : String(spawnError);
|
|
230
317
|
this.logger.warn(
|
|
231
|
-
`Sub-agent LLM config failed: ${errorMsg}. Falling back to parent's LLM config.`
|
|
318
|
+
`Sub-agent '${input.agentId}' LLM config failed: ${errorMsg}. Falling back to parent's full LLM config.`
|
|
232
319
|
);
|
|
233
|
-
|
|
320
|
+
llmMode = "parent";
|
|
234
321
|
buildOptions.inheritLlm = true;
|
|
235
|
-
subAgentConfig = await this.buildSubAgentConfig(buildOptions);
|
|
322
|
+
subAgentConfig = await this.buildSubAgentConfig(buildOptions, sessionId);
|
|
236
323
|
handle = await this.runtime.spawnAgent({
|
|
237
324
|
agentConfig: subAgentConfig,
|
|
238
325
|
ephemeral: true,
|
|
@@ -241,7 +328,8 @@ class RuntimeService {
|
|
|
241
328
|
parentId: this.parentId,
|
|
242
329
|
task: input.task,
|
|
243
330
|
autoApprove,
|
|
244
|
-
|
|
331
|
+
llmMode: "parent",
|
|
332
|
+
fallbackStage: "spawn",
|
|
245
333
|
spawnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
246
334
|
},
|
|
247
335
|
onBeforeStart: (agent) => {
|
|
@@ -261,7 +349,7 @@ class RuntimeService {
|
|
|
261
349
|
}
|
|
262
350
|
}
|
|
263
351
|
this.logger.info(
|
|
264
|
-
`Spawned sub-agent '${spawnedAgentId}' for task: ${input.task}${autoApprove ? " (auto-approve)" : ""}${
|
|
352
|
+
`Spawned sub-agent '${spawnedAgentId}' for task: ${input.task}${autoApprove ? " (auto-approve)" : ""}${llmMode === "parent" ? " (using parent LLM)" : ""}`
|
|
265
353
|
);
|
|
266
354
|
cleanupProgressTracking = this.setupProgressTracking(
|
|
267
355
|
handle,
|
|
@@ -269,11 +357,74 @@ class RuntimeService {
|
|
|
269
357
|
toolCallId,
|
|
270
358
|
sessionId
|
|
271
359
|
);
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
360
|
+
let result;
|
|
361
|
+
try {
|
|
362
|
+
result = await this.runtime.executeTask(
|
|
363
|
+
spawnedAgentId,
|
|
364
|
+
input.instructions,
|
|
365
|
+
timeout
|
|
366
|
+
);
|
|
367
|
+
} catch (execError) {
|
|
368
|
+
const isLlmExecError = this.isLLMError(execError);
|
|
369
|
+
if (llmMode === "parent") {
|
|
370
|
+
throw execError;
|
|
371
|
+
}
|
|
372
|
+
if (isLlmExecError && input.agentId && llmMode === "subagent") {
|
|
373
|
+
this.logger.warn(
|
|
374
|
+
`Sub-agent '${input.agentId}' LLM error during execution: ${execError instanceof Error ? execError.message : String(execError)}. Retrying with parent's full LLM config.`
|
|
375
|
+
);
|
|
376
|
+
try {
|
|
377
|
+
await this.runtime.stopAgent(spawnedAgentId);
|
|
378
|
+
} catch {
|
|
379
|
+
}
|
|
380
|
+
if (cleanupProgressTracking) {
|
|
381
|
+
cleanupProgressTracking();
|
|
382
|
+
}
|
|
383
|
+
llmMode = "parent";
|
|
384
|
+
buildOptions.inheritLlm = true;
|
|
385
|
+
subAgentConfig = await this.buildSubAgentConfig(buildOptions, sessionId);
|
|
386
|
+
handle = await this.runtime.spawnAgent({
|
|
387
|
+
agentConfig: subAgentConfig,
|
|
388
|
+
ephemeral: true,
|
|
389
|
+
group: this.parentId,
|
|
390
|
+
metadata: {
|
|
391
|
+
parentId: this.parentId,
|
|
392
|
+
task: input.task,
|
|
393
|
+
autoApprove,
|
|
394
|
+
llmMode: "parent",
|
|
395
|
+
fallbackStage: "execution",
|
|
396
|
+
spawnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
397
|
+
},
|
|
398
|
+
onBeforeStart: (agent) => {
|
|
399
|
+
if (!autoApprove) {
|
|
400
|
+
const delegatingHandler = (0, import_approval_delegation.createDelegatingApprovalHandler)(
|
|
401
|
+
this.parentAgent.services.approvalManager,
|
|
402
|
+
agent.config.agentId ?? "unknown",
|
|
403
|
+
this.logger
|
|
404
|
+
);
|
|
405
|
+
agent.setApprovalHandler(delegatingHandler);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
spawnedAgentId = handle.agentId;
|
|
410
|
+
this.logger.info(
|
|
411
|
+
`Re-spawned sub-agent '${spawnedAgentId}' for task: ${input.task} (using parent LLM)`
|
|
412
|
+
);
|
|
413
|
+
cleanupProgressTracking = this.setupProgressTracking(
|
|
414
|
+
handle,
|
|
415
|
+
input,
|
|
416
|
+
toolCallId,
|
|
417
|
+
sessionId
|
|
418
|
+
);
|
|
419
|
+
result = await this.runtime.executeTask(
|
|
420
|
+
spawnedAgentId,
|
|
421
|
+
input.instructions,
|
|
422
|
+
timeout
|
|
423
|
+
);
|
|
424
|
+
} else {
|
|
425
|
+
throw execError;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
277
428
|
const output = {
|
|
278
429
|
success: result.success
|
|
279
430
|
};
|
|
@@ -283,6 +434,9 @@ class RuntimeService {
|
|
|
283
434
|
if (result.error !== void 0) {
|
|
284
435
|
output.error = result.error;
|
|
285
436
|
}
|
|
437
|
+
if (llmMode === "parent") {
|
|
438
|
+
output.warning = `Sub-agent '${input.agentId}' used fallback LLM (parent's full config) due to an error with its configured model.`;
|
|
439
|
+
}
|
|
286
440
|
return output;
|
|
287
441
|
} catch (error) {
|
|
288
442
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -309,24 +463,56 @@ class RuntimeService {
|
|
|
309
463
|
* @param options.agentId - Agent ID from registry
|
|
310
464
|
* @param options.inheritLlm - Use parent's LLM config instead of sub-agent's
|
|
311
465
|
* @param options.autoApprove - Auto-approve all tool calls
|
|
466
|
+
* @param sessionId - Optional session ID to get session-specific LLM config
|
|
312
467
|
*/
|
|
313
|
-
async buildSubAgentConfig(options) {
|
|
468
|
+
async buildSubAgentConfig(options, sessionId) {
|
|
314
469
|
const { agentId, inheritLlm, autoApprove } = options;
|
|
315
470
|
const parentConfig = this.parentAgent.config;
|
|
471
|
+
const currentParentLLM = this.parentAgent.getCurrentLLMConfig(sessionId);
|
|
472
|
+
this.logger.debug(
|
|
473
|
+
`[RuntimeService] Building sub-agent config with LLM: ${currentParentLLM.provider}/${currentParentLLM.model}` + (sessionId ? ` (sessionId: ${sessionId})` : " (no sessionId)")
|
|
474
|
+
);
|
|
316
475
|
const toolConfirmationMode = autoApprove ? "auto-approve" : "manual";
|
|
317
476
|
if (agentId) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
477
|
+
let configPath = null;
|
|
478
|
+
try {
|
|
479
|
+
const registry = (0, import_registry.getAgentRegistry)();
|
|
480
|
+
if (!registry.hasAgent(agentId)) {
|
|
481
|
+
this.logger.warn(
|
|
482
|
+
`Agent '${agentId}' not found in registry. Trying bundled config paths.`
|
|
483
|
+
);
|
|
484
|
+
} else {
|
|
485
|
+
configPath = await registry.resolveAgent(agentId);
|
|
486
|
+
}
|
|
487
|
+
} catch (error) {
|
|
488
|
+
this.logger.warn(
|
|
489
|
+
`Failed to load agent registry for '${agentId}'. Trying bundled config paths. (${error instanceof Error ? error.message : String(error)})`
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
if (!configPath) {
|
|
493
|
+
configPath = this.resolveBundledAgentConfig(agentId);
|
|
494
|
+
}
|
|
495
|
+
if (configPath) {
|
|
496
|
+
this.logger.debug(`Loading agent config from registry/bundled path: ${configPath}`);
|
|
324
497
|
const loadedConfig = await (0, import_loader.loadAgentConfig)(configPath, this.logger);
|
|
325
498
|
let llmConfig = loadedConfig.llm;
|
|
326
499
|
if (inheritLlm) {
|
|
327
|
-
this.logger.debug(
|
|
328
|
-
|
|
500
|
+
this.logger.debug(
|
|
501
|
+
`Sub-agent '${agentId}' using parent LLM config (inheritLlm=true)`
|
|
502
|
+
);
|
|
503
|
+
llmConfig = { ...currentParentLLM };
|
|
504
|
+
} else {
|
|
505
|
+
const resolution = (0, import_llm_resolution.resolveSubAgentLLM)({
|
|
506
|
+
subAgentLLM: loadedConfig.llm,
|
|
507
|
+
parentLLM: currentParentLLM,
|
|
508
|
+
subAgentId: agentId
|
|
509
|
+
});
|
|
510
|
+
this.logger.debug(`Sub-agent LLM resolution: ${resolution.reason}`);
|
|
511
|
+
llmConfig = resolution.llm;
|
|
329
512
|
}
|
|
513
|
+
const filteredCustomTools = loadedConfig.customTools ? loadedConfig.customTools.filter(
|
|
514
|
+
(tool) => typeof tool === "object" && tool !== null && "type" in tool && tool.type !== "agent-spawner"
|
|
515
|
+
) : void 0;
|
|
330
516
|
return {
|
|
331
517
|
...loadedConfig,
|
|
332
518
|
llm: llmConfig,
|
|
@@ -334,6 +520,7 @@ class RuntimeService {
|
|
|
334
520
|
...loadedConfig.toolConfirmation,
|
|
335
521
|
mode: toolConfirmationMode
|
|
336
522
|
},
|
|
523
|
+
customTools: filteredCustomTools,
|
|
337
524
|
// Suppress sub-agent console logs entirely using silent transport
|
|
338
525
|
logger: {
|
|
339
526
|
level: "error",
|
|
@@ -341,14 +528,30 @@ class RuntimeService {
|
|
|
341
528
|
}
|
|
342
529
|
};
|
|
343
530
|
}
|
|
531
|
+
this.logger.warn(
|
|
532
|
+
`Agent '${agentId}' not found in registry or bundled paths. Using default config.`
|
|
533
|
+
);
|
|
344
534
|
}
|
|
345
535
|
const config = {
|
|
346
|
-
llm: { ...
|
|
536
|
+
llm: { ...currentParentLLM },
|
|
347
537
|
// Default system prompt for sub-agents
|
|
348
538
|
systemPrompt: "You are a helpful sub-agent. Complete the task given to you efficiently and concisely.",
|
|
349
539
|
toolConfirmation: {
|
|
350
540
|
mode: toolConfirmationMode
|
|
351
541
|
},
|
|
542
|
+
// Inherit MCP servers from parent so subagent has tool access
|
|
543
|
+
mcpServers: parentConfig.mcpServers ? { ...parentConfig.mcpServers } : {},
|
|
544
|
+
// Inherit internal tools from parent, excluding tools that don't work in subagent context
|
|
545
|
+
// - ask_user: Subagents can't interact with the user directly
|
|
546
|
+
// - invoke_skill: Avoid nested skill invocations for simplicity
|
|
547
|
+
internalTools: parentConfig.internalTools ? parentConfig.internalTools.filter(
|
|
548
|
+
(tool) => tool !== "ask_user" && tool !== "invoke_skill"
|
|
549
|
+
) : [],
|
|
550
|
+
// Inherit custom tools from parent, excluding agent-spawner to prevent nested spawning (depth=1 limit)
|
|
551
|
+
// - agent-spawner: Sub-agents should not spawn their own sub-agents
|
|
552
|
+
customTools: parentConfig.customTools ? parentConfig.customTools.filter(
|
|
553
|
+
(tool) => typeof tool === "object" && tool !== null && "type" in tool && tool.type !== "agent-spawner"
|
|
554
|
+
) : [],
|
|
352
555
|
// Suppress sub-agent console logs entirely using silent transport
|
|
353
556
|
logger: {
|
|
354
557
|
level: "error",
|
|
@@ -362,15 +565,24 @@ class RuntimeService {
|
|
|
362
565
|
* Returns agent metadata from registry, filtered by allowedAgents if configured.
|
|
363
566
|
*/
|
|
364
567
|
getAvailableAgents() {
|
|
365
|
-
|
|
366
|
-
|
|
568
|
+
let allAgents;
|
|
569
|
+
try {
|
|
570
|
+
const registry = (0, import_registry.getAgentRegistry)();
|
|
571
|
+
allAgents = registry.getAvailableAgents();
|
|
572
|
+
} catch (error) {
|
|
573
|
+
this.logger.warn(
|
|
574
|
+
`Failed to load agent registry for spawn_agent description: ${error instanceof Error ? error.message : String(error)}`
|
|
575
|
+
);
|
|
576
|
+
if (this.config.allowedAgents && this.config.allowedAgents.length > 0) {
|
|
577
|
+
return this.config.allowedAgents.map((id) => this.createFallbackRegistryEntry(id));
|
|
578
|
+
}
|
|
579
|
+
return [];
|
|
580
|
+
}
|
|
367
581
|
if (this.config.allowedAgents && this.config.allowedAgents.length > 0) {
|
|
368
582
|
const result = [];
|
|
369
583
|
for (const id of this.config.allowedAgents) {
|
|
370
584
|
const agent = allAgents[id];
|
|
371
|
-
|
|
372
|
-
result.push(agent);
|
|
373
|
-
}
|
|
585
|
+
result.push(agent ?? this.createFallbackRegistryEntry(id));
|
|
374
586
|
}
|
|
375
587
|
return result;
|
|
376
588
|
}
|