18
19
META_FILE_NAME = "plugin.json"
20
CONFIG_FILE_NAME = "config.json"
21
+CONFIG_DEFAULT_FILE_NAME = "config.default.json"
22
DISABLED_FILE_NAME = ".disabled"
23
ENABLED_FILE_NAME = ".enabled"
24
141
)
142
return paths
143
143
-def get_enabled_plugin_paths(agent:Agent|None, *subpaths: str) -> List[str]:
144
+
145
+def get_enabled_plugin_paths(agent: Agent | None, *subpaths: str) -> List[str]:
146
enabled = get_enabled_plugins(agent)
147
paths: list[str] = []
148
169
170
if agent:
171
from python.helpers import subagents
170
-
172
+
173
for plugin in plugins:
174
# plugins are toggled via .enabled / .disabled files
175
# every plugin is on by default, unless disabled in usr dir
177
178
if agent:
179
agent_paths = subagents.get_paths(
178
- agent,
179
- files.PLUGINS_DIR,
180
- plugin,
181
- must_exist_completely=True,
182
- include_default=False,
183
- include_user=True,
184
- include_plugins=False,
185
- include_project=True
186
- )
180
+ agent,
181
+ files.PLUGINS_DIR,
182
+ plugin,
183
+ must_exist_completely=True,
184
+ include_default=False,
185
+ include_user=True,
186
+ include_plugins=False,
187
+ include_project=True,
188
+ )
189
190
# go through agent paths in reverse order and determine the state
191
for agent_path in reversed(agent_paths):
192
if enabled:
191
- enabled = not files.exists(files.get_abs_path(agent_path, DISABLED_FILE_NAME))
193
+ enabled = not files.exists(
194
+ files.get_abs_path(agent_path, DISABLED_FILE_NAME)
195
+ )
196
else:
193
- enabled = files.exists(files.get_abs_path(agent_path, ENABLED_FILE_NAME))
194
-
197
+ enabled = files.exists(
198
+ files.get_abs_path(agent_path, ENABLED_FILE_NAME)
199
+ )
200
201
if enabled:
202
active.append(plugin)
198
-
199
- return active
203
204
+ return active
205
206
207
def get_webui_extensions(extension_point: str, filters: List[str] | None = None):
217
return entries
218
219
216
-def get_plugin_config(plugin_name: str, agent: Agent | None):
217
- file_path = find_plugin_asset(plugin_name, CONFIG_FILE_NAME, agent=agent)
218
- if file_path:
220
+def get_plugin_config(plugin_name: str, agent: Agent | None, project_name:str|None=None, agent_profile:str|None=None):
221
+
222
+ if project_name is None and agent is not None:
223
+ from python.helpers import projects
224
+ project_name = projects.get_context_project_name(agent.context)
225
+ if agent_profile is None and agent is not None:
226
+ agent_profile = agent.config.profile
227
+
228
+ # find config.json in all possible places
229
+ file_path = find_plugin_asset(plugin_name, CONFIG_FILE_NAME, project_name=project_name, agent_profile=agent_profile)
230
+ # use default config if not found
231
+ if not file_path:
232
+ file_path = files.get_abs_path(
233
+ find_plugin_dir(plugin_name), CONFIG_DEFAULT_FILE_NAME
234
+ )
235
+ if file_path and files.exists(file_path):
236
return json.loads(files.read_file(file_path))
237
return None
238
247
files.write_file(file_path, json.dumps(settings))
248
249
233
-def find_plugin_asset(plugin_name: str, *subpaths: str, agent: Agent | None = None):
234
- project_name = ""
250
+def find_plugin_asset(plugin_name: str, *subpaths: str, project_name="", agent_profile=""):
251
+ result = find_plugin_assets(
252
+ *subpaths,
253
+ plugin_name=plugin_name,
254
+ project_name=project_name,
255
+ agent_profile=agent_profile,
256
+ only_first=True
257
+ )
258
+ return result[0]["path"] if result else None
259
236
- if agent:
237
- profile_name = agent.config.profile if agent and agent.config.profile else ""
260
239
- from python.helpers import projects
261
+def find_plugin_assets(
262
+ *subpaths: str,
263
+ plugin_name: str = "*",
264
+ project_name: str = "*",
265
+ agent_profile: str = "*",
266
+ only_first: bool = False,
267
+) -> list[dict]:
268
+ from python.helpers import projects, subagents
269
241
- project_name = projects.get_context_project_name(agent.context) or ""
270
+ results: list[dict] = []
271
243
- if project_name and profile_name:
244
- # project/.a0proj/agents/<profile>/plugins/<plugin_name>/...
245
- project_agent_file = projects.get_project_meta(
272
+ def _collect(path: str, proj: str, profile: str) -> bool:
273
+ matched_paths = (
274
+ files.find_existing_paths_by_pattern(path)
275
+ if "*" in path
276
+ else ([path] if files.exists(path) else [])
277
+ )
278
+ for matched in matched_paths:
279
+ results.append(
280
+ {"project_name": proj, "agent_profile": profile, "path": matched}
281
+ )
282
+ if only_first:
283
+ return True
284
+
285
+ # project/.a0proj/agents/<profile>/plugins/<plugin_name>/...
286
+ if project_name:
287
+ if agent_profile:
288
+ path = projects.get_project_meta(
289
project_name,
290
files.AGENTS_DIR,
248
- profile_name,
291
+ agent_profile,
292
files.PLUGINS_DIR,
293
plugin_name,
294
*subpaths,
295
)
253
- if files.exists(project_agent_file):
254
- return project_agent_file
255
-
256
- if project_name:
296
+ if _collect(path, project_name, agent_profile):
297
+ return results
298
+ else:
299
# project/.a0proj/plugins/<plugin_name>/...
258
- project_file = projects.get_project_meta(
300
+ path = projects.get_project_meta(
301
project_name, files.PLUGINS_DIR, plugin_name, *subpaths
302
)
261
- if files.exists(project_file):
262
- return project_file
263
-
264
- if profile_name:
265
- from python.helpers import subagents
303
+ if _collect(path, project_name, ""):
304
+ return results
305
267
- # usr/agents/<profile>/plugins/<plugin_name>/...
268
- path = files.get_abs_path(
269
- subagents.USER_AGENTS_DIR,
270
- profile_name,
271
- files.PLUGINS_DIR,
272
- plugin_name,
273
- *subpaths,
274
- )
275
- if files.exists(path):
276
- return path
306
+ # usr/agents/<profile>/plugins/<plugin_name>/...
307
+ if agent_profile:
308
+ path = files.get_abs_path(
309
+ subagents.USER_AGENTS_DIR,
310
+ agent_profile,
311
+ files.PLUGINS_DIR,
312
+ plugin_name,
313
+ *subpaths,
314
+ )
315
+ if _collect(path, "", agent_profile):
316
+ return results
317
278
- # agents/<profile>/plugins/<plugin_name>/...
318
+ # usr?/plugins/<any_plugin>/agents/<profile>/plugins/<plugin_name>/...
319
+ for plugin_base in get_enabled_plugin_paths(None):
320
path = files.get_abs_path(
280
- subagents.DEFAULT_AGENTS_DIR,
281
- profile_name,
321
+ plugin_base,
322
+ files.AGENTS_DIR,
323
+ agent_profile,
324
files.PLUGINS_DIR,
325
plugin_name,
326
*subpaths,
327
)
286
- if files.exists(path):
287
- return path
328
+ if _collect(path, "", agent_profile):
329
+ return results
330
+
331
+ # agents/<profile>/plugins/<plugin_name>/...
332
+ path = files.get_abs_path(
333
+ subagents.DEFAULT_AGENTS_DIR,
334
+ agent_profile,
335
+ files.PLUGINS_DIR,
336
+ plugin_name,
337
+ *subpaths,
338
+ )
339
+ if _collect(path, "", agent_profile):
340
+ return results
341
342
# usr/plugins/<plugin_name>/...
343
path = files.get_abs_path(files.USER_DIR, files.PLUGINS_DIR, plugin_name, *subpaths)
291
- if files.exists(path):
292
- return path
344
+ if _collect(path, "", ""):
345
+ return results
346
347
# plugins/<plugin_name>/...
348
path = files.get_abs_path(files.PLUGINS_DIR, plugin_name, *subpaths)
296
- if files.exists(path):
297
- return path
349
+ _collect(path, "", "")
350
299
- return None
351
+ return results
352
353
354
def determine_plugin_asset_path(