agencode 0.1.0__py3-none-any.whl
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.
- agencli/__init__.py +5 -0
- agencli/__main__.py +9 -0
- agencli/agents/__init__.py +1 -0
- agencli/agents/editor.py +110 -0
- agencli/agents/factory.py +335 -0
- agencli/agents/management_tools.py +277 -0
- agencli/agents/prebuilt/__init__.py +1 -0
- agencli/agents/prebuilt/catalog.py +66 -0
- agencli/agents/registry.py +50 -0
- agencli/agents/runtime.py +266 -0
- agencli/agents/supervisor.py +67 -0
- agencli/cli.py +561 -0
- agencli/core/__init__.py +1 -0
- agencli/core/config.py +179 -0
- agencli/core/keystore.py +14 -0
- agencli/core/logger.py +17 -0
- agencli/core/paths.py +37 -0
- agencli/core/session.py +513 -0
- agencli/mcp/__init__.py +1 -0
- agencli/mcp/client.py +33 -0
- agencli/mcp/config.py +99 -0
- agencli/providers/__init__.py +1 -0
- agencli/providers/model.py +180 -0
- agencli/skills/__init__.py +37 -0
- agencli/skills/cli_backend.py +446 -0
- agencli/skills/loader.py +77 -0
- agencli/skills/manager.py +153 -0
- agencli/tools/__init__.py +1 -0
- agencli/tools/mcp.py +106 -0
- agencli/tui/__init__.py +1 -0
- agencli/tui/app.py +4274 -0
- agencli/tui/commands.py +86 -0
- agencli/tui/screens.py +939 -0
- agencli/tui/trace.py +334 -0
- agencli/tui/voice.py +77 -0
- agencode-0.1.0.dist-info/METADATA +44 -0
- agencode-0.1.0.dist-info/RECORD +39 -0
- agencode-0.1.0.dist-info/WHEEL +4 -0
- agencode-0.1.0.dist-info/entry_points.txt +3 -0
agencli/__init__.py
ADDED
agencli/__main__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Agent construction and registration helpers."""
|
agencli/agents/editor.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Collection, Iterable, Sequence
|
|
4
|
+
|
|
5
|
+
from agencli.agents.factory import AgentSpec
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def parse_token_list(raw: str) -> list[str]:
|
|
9
|
+
tokens = [token.strip() for chunk in raw.replace("\n", ",").split(",") for token in [chunk.strip()]]
|
|
10
|
+
return _dedupe([token for token in tokens if token])
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def format_token_list(values: Sequence[str]) -> str:
|
|
14
|
+
return ", ".join(value for value in values if value)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def partition_skill_tokens(
|
|
18
|
+
skill_tokens: Sequence[str],
|
|
19
|
+
installed_skill_names: Collection[str],
|
|
20
|
+
) -> tuple[list[str], list[str]]:
|
|
21
|
+
installed_names = set(installed_skill_names)
|
|
22
|
+
managed: list[str] = []
|
|
23
|
+
extra: list[str] = []
|
|
24
|
+
for token in skill_tokens:
|
|
25
|
+
if token == "installed" or token in installed_names:
|
|
26
|
+
managed.append(token)
|
|
27
|
+
else:
|
|
28
|
+
extra.append(token)
|
|
29
|
+
return _dedupe(managed), _dedupe(extra)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def suggest_custom_agent_name(base_name: str, existing_names: Collection[str]) -> str:
|
|
33
|
+
existing = set(existing_names)
|
|
34
|
+
normalized_base = base_name.strip() or "custom-agent"
|
|
35
|
+
candidate = normalized_base if normalized_base not in existing else f"{normalized_base}-custom"
|
|
36
|
+
if candidate not in existing:
|
|
37
|
+
return candidate
|
|
38
|
+
|
|
39
|
+
index = 2
|
|
40
|
+
while f"{candidate}-{index}" in existing:
|
|
41
|
+
index += 1
|
|
42
|
+
return f"{candidate}-{index}"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def copy_agent_spec_for_customization(
|
|
46
|
+
spec: AgentSpec | None,
|
|
47
|
+
*,
|
|
48
|
+
existing_names: Collection[str],
|
|
49
|
+
default_model: str,
|
|
50
|
+
) -> AgentSpec:
|
|
51
|
+
if spec is None:
|
|
52
|
+
return AgentSpec(
|
|
53
|
+
name=suggest_custom_agent_name("custom-agent", existing_names),
|
|
54
|
+
model=default_model,
|
|
55
|
+
system_prompt="You are a helpful AI agent. Work carefully and explain your reasoning clearly.",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
copied = AgentSpec.from_dict(spec.serializable_dict())
|
|
59
|
+
copied.name = suggest_custom_agent_name(spec.name, existing_names)
|
|
60
|
+
if not copied.model:
|
|
61
|
+
copied.model = default_model
|
|
62
|
+
return copied
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def build_agent_spec_from_editor(
|
|
66
|
+
*,
|
|
67
|
+
base_spec: AgentSpec | None,
|
|
68
|
+
name: str,
|
|
69
|
+
model: str,
|
|
70
|
+
description: str,
|
|
71
|
+
system_prompt: str,
|
|
72
|
+
workspace_dir: str,
|
|
73
|
+
mcp_servers_raw: str,
|
|
74
|
+
selected_skill_tokens: Iterable[str],
|
|
75
|
+
extra_skill_tokens_raw: str,
|
|
76
|
+
) -> AgentSpec:
|
|
77
|
+
normalized_name = name.strip()
|
|
78
|
+
normalized_model = model.strip()
|
|
79
|
+
normalized_prompt = system_prompt.strip()
|
|
80
|
+
if not normalized_name:
|
|
81
|
+
raise ValueError("Agent name is required.")
|
|
82
|
+
if not normalized_model:
|
|
83
|
+
raise ValueError("Agent model is required.")
|
|
84
|
+
if not normalized_prompt:
|
|
85
|
+
raise ValueError("System prompt is required.")
|
|
86
|
+
|
|
87
|
+
seeded = AgentSpec.from_dict(base_spec.serializable_dict()) if base_spec is not None else AgentSpec(
|
|
88
|
+
name=normalized_name,
|
|
89
|
+
model=normalized_model,
|
|
90
|
+
system_prompt=normalized_prompt,
|
|
91
|
+
)
|
|
92
|
+
seeded.name = normalized_name
|
|
93
|
+
seeded.model = normalized_model
|
|
94
|
+
seeded.description = description.strip()
|
|
95
|
+
seeded.system_prompt = normalized_prompt
|
|
96
|
+
seeded.workspace_dir = workspace_dir.strip() or None
|
|
97
|
+
seeded.mcp_servers = parse_token_list(mcp_servers_raw)
|
|
98
|
+
seeded.skills = _dedupe([*selected_skill_tokens, *parse_token_list(extra_skill_tokens_raw)])
|
|
99
|
+
return seeded
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _dedupe(values: Iterable[str]) -> list[str]:
|
|
103
|
+
seen: set[str] = set()
|
|
104
|
+
deduped: list[str] = []
|
|
105
|
+
for value in values:
|
|
106
|
+
if value in seen:
|
|
107
|
+
continue
|
|
108
|
+
seen.add(value)
|
|
109
|
+
deduped.append(value)
|
|
110
|
+
return deduped
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from agencli.core.config import AgenCLIConfig
|
|
7
|
+
from agencli.core.session import ensure_langgraph_checkpointer, ensure_langgraph_checkpointer_async
|
|
8
|
+
from agencli.providers.model import init_model
|
|
9
|
+
from agencli.skills.loader import resolve_skill_sources
|
|
10
|
+
from agencli.tools.mcp import load_mcp_tools, load_mcp_tools_async
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(slots=True)
|
|
14
|
+
class SubAgentSpec:
|
|
15
|
+
name: str
|
|
16
|
+
description: str
|
|
17
|
+
system_prompt: str
|
|
18
|
+
model: str | None = None
|
|
19
|
+
skills: list[str] = field(default_factory=list)
|
|
20
|
+
mcp_servers: list[str] = field(default_factory=list)
|
|
21
|
+
workspace_dir: str | None = None
|
|
22
|
+
|
|
23
|
+
def serializable_dict(self) -> dict[str, Any]:
|
|
24
|
+
return {
|
|
25
|
+
"name": self.name,
|
|
26
|
+
"description": self.description,
|
|
27
|
+
"system_prompt": self.system_prompt,
|
|
28
|
+
"model": self.model,
|
|
29
|
+
"skills": self.skills,
|
|
30
|
+
"mcp_servers": self.mcp_servers,
|
|
31
|
+
"workspace_dir": self.workspace_dir,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def from_dict(cls, raw: dict[str, Any]) -> "SubAgentSpec":
|
|
36
|
+
return cls(
|
|
37
|
+
name=raw["name"],
|
|
38
|
+
description=raw["description"],
|
|
39
|
+
system_prompt=raw["system_prompt"],
|
|
40
|
+
model=raw.get("model"),
|
|
41
|
+
skills=list(raw.get("skills", [])),
|
|
42
|
+
mcp_servers=list(raw.get("mcp_servers", [])),
|
|
43
|
+
workspace_dir=raw.get("workspace_dir"),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(slots=True)
|
|
48
|
+
class AgentSpec:
|
|
49
|
+
name: str
|
|
50
|
+
model: str
|
|
51
|
+
system_prompt: str
|
|
52
|
+
description: str = ""
|
|
53
|
+
tools: list[Any] = field(default_factory=list)
|
|
54
|
+
subagents: list[SubAgentSpec | dict[str, Any]] = field(default_factory=list)
|
|
55
|
+
skills: list[str] = field(default_factory=list)
|
|
56
|
+
mcp_servers: list[str] = field(default_factory=list)
|
|
57
|
+
workspace_dir: str | None = None
|
|
58
|
+
|
|
59
|
+
def serializable_dict(self) -> dict[str, Any]:
|
|
60
|
+
return {
|
|
61
|
+
"name": self.name,
|
|
62
|
+
"model": self.model,
|
|
63
|
+
"system_prompt": self.system_prompt,
|
|
64
|
+
"description": self.description,
|
|
65
|
+
"subagents": [_serialize_subagent(subagent) for subagent in self.subagents],
|
|
66
|
+
"skills": self.skills,
|
|
67
|
+
"mcp_servers": self.mcp_servers,
|
|
68
|
+
"workspace_dir": self.workspace_dir,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def from_dict(cls, raw: dict[str, Any]) -> "AgentSpec":
|
|
73
|
+
return cls(
|
|
74
|
+
name=raw["name"],
|
|
75
|
+
model=raw["model"],
|
|
76
|
+
system_prompt=raw["system_prompt"],
|
|
77
|
+
description=raw.get("description", ""),
|
|
78
|
+
subagents=[_deserialize_subagent(subagent) for subagent in raw.get("subagents", [])],
|
|
79
|
+
skills=list(raw.get("skills", [])),
|
|
80
|
+
mcp_servers=list(raw.get("mcp_servers", [])),
|
|
81
|
+
workspace_dir=raw.get("workspace_dir"),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def build_agent(
|
|
86
|
+
spec: AgentSpec,
|
|
87
|
+
config: AgenCLIConfig | None = None,
|
|
88
|
+
*,
|
|
89
|
+
session_name: str = "default",
|
|
90
|
+
checkpointer: Any | None = None,
|
|
91
|
+
diagnostics: list[str] | None = None,
|
|
92
|
+
) -> Any:
|
|
93
|
+
"""Build a DeepAgent graph lazily once the runtime dependencies are installed."""
|
|
94
|
+
try:
|
|
95
|
+
from deepagents import create_deep_agent
|
|
96
|
+
from deepagents.backends import FilesystemBackend, LocalShellBackend
|
|
97
|
+
except ImportError as exc:
|
|
98
|
+
raise RuntimeError(
|
|
99
|
+
"Deep agent runtime dependencies are not installed yet. Run `uv sync` after dependencies are added."
|
|
100
|
+
) from exc
|
|
101
|
+
|
|
102
|
+
resolved_tools = list(spec.tools)
|
|
103
|
+
if config is None:
|
|
104
|
+
try:
|
|
105
|
+
from langchain.chat_models import init_chat_model
|
|
106
|
+
except ImportError as exc:
|
|
107
|
+
raise RuntimeError(
|
|
108
|
+
"langchain is not installed yet. Run `uv sync` after dependencies are added."
|
|
109
|
+
) from exc
|
|
110
|
+
model = init_chat_model(spec.model)
|
|
111
|
+
workspace_dir = spec.workspace_dir
|
|
112
|
+
resolved_subagents = _resolve_subagents(spec.subagents, model_name=spec.model)
|
|
113
|
+
resolved_skills = list(spec.skills)
|
|
114
|
+
else:
|
|
115
|
+
model = init_model(config, model_name=spec.model)
|
|
116
|
+
workspace_dir = spec.workspace_dir or config.workspace_dir
|
|
117
|
+
if checkpointer is None:
|
|
118
|
+
checkpointer = ensure_langgraph_checkpointer(config.sessions_dir, session_name=session_name)
|
|
119
|
+
if spec.name == "supervisor-agent":
|
|
120
|
+
from agencli.agents.management_tools import build_supervisor_management_tools
|
|
121
|
+
|
|
122
|
+
resolved_tools.extend(build_supervisor_management_tools(config))
|
|
123
|
+
if spec.mcp_servers:
|
|
124
|
+
resolved_tools.extend(
|
|
125
|
+
load_mcp_tools(
|
|
126
|
+
config.mcp_config_path,
|
|
127
|
+
server_names=spec.mcp_servers,
|
|
128
|
+
diagnostics=diagnostics,
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
resolved_subagents = _resolve_subagents(
|
|
132
|
+
spec.subagents,
|
|
133
|
+
config=config,
|
|
134
|
+
model_name=spec.model,
|
|
135
|
+
diagnostics=diagnostics,
|
|
136
|
+
)
|
|
137
|
+
resolved_skills = resolve_skill_sources(spec.skills, config.skills_dir)
|
|
138
|
+
|
|
139
|
+
backend = _build_backend(spec.name, workspace_dir, FilesystemBackend, LocalShellBackend)
|
|
140
|
+
return create_deep_agent(
|
|
141
|
+
model=model,
|
|
142
|
+
tools=resolved_tools,
|
|
143
|
+
system_prompt=spec.system_prompt,
|
|
144
|
+
subagents=resolved_subagents,
|
|
145
|
+
skills=resolved_skills or None,
|
|
146
|
+
backend=backend,
|
|
147
|
+
checkpointer=checkpointer,
|
|
148
|
+
name=spec.name,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
async def build_agent_async(
|
|
153
|
+
spec: AgentSpec,
|
|
154
|
+
config: AgenCLIConfig | None = None,
|
|
155
|
+
*,
|
|
156
|
+
session_name: str = "default",
|
|
157
|
+
checkpointer: Any | None = None,
|
|
158
|
+
diagnostics: list[str] | None = None,
|
|
159
|
+
) -> Any:
|
|
160
|
+
try:
|
|
161
|
+
from deepagents import create_deep_agent
|
|
162
|
+
from deepagents.backends import FilesystemBackend, LocalShellBackend
|
|
163
|
+
except ImportError as exc:
|
|
164
|
+
raise RuntimeError(
|
|
165
|
+
"Deep agent runtime dependencies are not installed yet. Run `uv sync` after dependencies are added."
|
|
166
|
+
) from exc
|
|
167
|
+
|
|
168
|
+
resolved_tools = list(spec.tools)
|
|
169
|
+
if config is None:
|
|
170
|
+
return build_agent(
|
|
171
|
+
spec,
|
|
172
|
+
config=None,
|
|
173
|
+
session_name=session_name,
|
|
174
|
+
checkpointer=checkpointer,
|
|
175
|
+
diagnostics=diagnostics,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
model = init_model(config, model_name=spec.model)
|
|
179
|
+
workspace_dir = spec.workspace_dir or config.workspace_dir
|
|
180
|
+
if checkpointer is None:
|
|
181
|
+
checkpointer = await ensure_langgraph_checkpointer_async(config.sessions_dir, session_name=session_name)
|
|
182
|
+
if spec.name == "supervisor-agent":
|
|
183
|
+
from agencli.agents.management_tools import build_supervisor_management_tools
|
|
184
|
+
|
|
185
|
+
resolved_tools.extend(build_supervisor_management_tools(config))
|
|
186
|
+
if spec.mcp_servers:
|
|
187
|
+
resolved_tools.extend(
|
|
188
|
+
await load_mcp_tools_async(
|
|
189
|
+
config.mcp_config_path,
|
|
190
|
+
server_names=spec.mcp_servers,
|
|
191
|
+
diagnostics=diagnostics,
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
resolved_subagents = await _resolve_subagents_async(
|
|
195
|
+
spec.subagents,
|
|
196
|
+
config=config,
|
|
197
|
+
model_name=spec.model,
|
|
198
|
+
diagnostics=diagnostics,
|
|
199
|
+
)
|
|
200
|
+
resolved_skills = resolve_skill_sources(spec.skills, config.skills_dir)
|
|
201
|
+
|
|
202
|
+
backend = _build_backend(spec.name, workspace_dir, FilesystemBackend, LocalShellBackend)
|
|
203
|
+
return create_deep_agent(
|
|
204
|
+
model=model,
|
|
205
|
+
tools=resolved_tools,
|
|
206
|
+
system_prompt=spec.system_prompt,
|
|
207
|
+
subagents=resolved_subagents,
|
|
208
|
+
skills=resolved_skills or None,
|
|
209
|
+
backend=backend,
|
|
210
|
+
checkpointer=checkpointer,
|
|
211
|
+
name=spec.name,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _serialize_subagent(subagent: SubAgentSpec | dict[str, Any]) -> dict[str, Any]:
|
|
216
|
+
if isinstance(subagent, SubAgentSpec):
|
|
217
|
+
return {"kind": "spec", **subagent.serializable_dict()}
|
|
218
|
+
if isinstance(subagent, dict) and "runnable" in subagent:
|
|
219
|
+
raise ValueError("Compiled subagents cannot be serialized into agent registry JSON.")
|
|
220
|
+
if isinstance(subagent, dict):
|
|
221
|
+
return dict(subagent)
|
|
222
|
+
raise TypeError(f"Unsupported subagent type: {type(subagent)!r}")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _deserialize_subagent(raw: dict[str, Any]) -> SubAgentSpec | dict[str, Any]:
|
|
226
|
+
if raw.get("kind") == "spec":
|
|
227
|
+
payload = dict(raw)
|
|
228
|
+
payload.pop("kind", None)
|
|
229
|
+
return SubAgentSpec.from_dict(payload)
|
|
230
|
+
if {"name", "description", "system_prompt"}.issubset(raw):
|
|
231
|
+
return SubAgentSpec.from_dict(raw)
|
|
232
|
+
return raw
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _build_backend(
|
|
236
|
+
agent_name: str,
|
|
237
|
+
workspace_dir: str | None,
|
|
238
|
+
filesystem_backend_cls: Any,
|
|
239
|
+
local_shell_backend_cls: Any,
|
|
240
|
+
):
|
|
241
|
+
shell_enabled_agents = {"shell-agent", "coding-agent", "supervisor-agent"}
|
|
242
|
+
backend_cls = local_shell_backend_cls if agent_name in shell_enabled_agents else filesystem_backend_cls
|
|
243
|
+
if workspace_dir:
|
|
244
|
+
return backend_cls(root_dir=workspace_dir)
|
|
245
|
+
return backend_cls()
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def _resolve_subagents(
|
|
249
|
+
subagents: list[SubAgentSpec | dict[str, Any]],
|
|
250
|
+
*,
|
|
251
|
+
config: AgenCLIConfig | None = None,
|
|
252
|
+
model_name: str,
|
|
253
|
+
diagnostics: list[str] | None = None,
|
|
254
|
+
) -> list[dict[str, Any]]:
|
|
255
|
+
resolved: list[dict[str, Any]] = []
|
|
256
|
+
for subagent in subagents:
|
|
257
|
+
if isinstance(subagent, SubAgentSpec):
|
|
258
|
+
tools: list[Any] = []
|
|
259
|
+
if config is not None and subagent.mcp_servers:
|
|
260
|
+
tools.extend(
|
|
261
|
+
load_mcp_tools(
|
|
262
|
+
config.mcp_config_path,
|
|
263
|
+
server_names=subagent.mcp_servers,
|
|
264
|
+
diagnostics=diagnostics,
|
|
265
|
+
)
|
|
266
|
+
)
|
|
267
|
+
elif subagent.mcp_servers:
|
|
268
|
+
raise RuntimeError("Subagents with MCP servers require a resolved AgenCLI config.")
|
|
269
|
+
payload: dict[str, Any] = {
|
|
270
|
+
"name": subagent.name,
|
|
271
|
+
"description": subagent.description,
|
|
272
|
+
"system_prompt": subagent.system_prompt,
|
|
273
|
+
"tools": tools,
|
|
274
|
+
}
|
|
275
|
+
if subagent.model:
|
|
276
|
+
payload["model"] = init_model(config, model_name=subagent.model) if config is not None else subagent.model
|
|
277
|
+
elif config is not None:
|
|
278
|
+
payload["model"] = init_model(config, model_name=model_name)
|
|
279
|
+
else:
|
|
280
|
+
payload["model"] = model_name
|
|
281
|
+
if subagent.skills:
|
|
282
|
+
payload["skills"] = (
|
|
283
|
+
resolve_skill_sources(subagent.skills, config.skills_dir)
|
|
284
|
+
if config is not None
|
|
285
|
+
else list(subagent.skills)
|
|
286
|
+
)
|
|
287
|
+
resolved.append(payload)
|
|
288
|
+
else:
|
|
289
|
+
resolved.append(dict(subagent))
|
|
290
|
+
return resolved
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
async def _resolve_subagents_async(
|
|
294
|
+
subagents: list[SubAgentSpec | dict[str, Any]],
|
|
295
|
+
*,
|
|
296
|
+
config: AgenCLIConfig | None = None,
|
|
297
|
+
model_name: str,
|
|
298
|
+
diagnostics: list[str] | None = None,
|
|
299
|
+
) -> list[dict[str, Any]]:
|
|
300
|
+
resolved: list[dict[str, Any]] = []
|
|
301
|
+
for subagent in subagents:
|
|
302
|
+
if isinstance(subagent, SubAgentSpec):
|
|
303
|
+
tools: list[Any] = []
|
|
304
|
+
if config is not None and subagent.mcp_servers:
|
|
305
|
+
tools.extend(
|
|
306
|
+
await load_mcp_tools_async(
|
|
307
|
+
config.mcp_config_path,
|
|
308
|
+
server_names=subagent.mcp_servers,
|
|
309
|
+
diagnostics=diagnostics,
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
elif subagent.mcp_servers:
|
|
313
|
+
raise RuntimeError("Subagents with MCP servers require a resolved AgenCLI config.")
|
|
314
|
+
payload: dict[str, Any] = {
|
|
315
|
+
"name": subagent.name,
|
|
316
|
+
"description": subagent.description,
|
|
317
|
+
"system_prompt": subagent.system_prompt,
|
|
318
|
+
"tools": tools,
|
|
319
|
+
}
|
|
320
|
+
if subagent.model:
|
|
321
|
+
payload["model"] = init_model(config, model_name=subagent.model) if config is not None else subagent.model
|
|
322
|
+
elif config is not None:
|
|
323
|
+
payload["model"] = init_model(config, model_name=model_name)
|
|
324
|
+
else:
|
|
325
|
+
payload["model"] = model_name
|
|
326
|
+
if subagent.skills:
|
|
327
|
+
payload["skills"] = (
|
|
328
|
+
resolve_skill_sources(subagent.skills, config.skills_dir)
|
|
329
|
+
if config is not None
|
|
330
|
+
else list(subagent.skills)
|
|
331
|
+
)
|
|
332
|
+
resolved.append(payload)
|
|
333
|
+
else:
|
|
334
|
+
resolved.append(dict(subagent))
|
|
335
|
+
return resolved
|