Files
deepagents/libs/code/deepagents_code/plugins/_json.py
T
Johannes du Plessis 0187d14b83 feat(code): add plugin marketplace support (#4554)
`deepagents-code` now supports experimental plugin marketplaces with
namespaced skills and MCP servers. Enable with
`DEEPAGENTS_CODE_EXPERIMENTAL=1`.

Docs: https://github.com/langchain-ai/docs/pull/4905

---

`deepagents-code` can now manage experimental plugin marketplaces and
load installed plugins that contribute namespaced skills and MCP
servers. The new plugin manager establishes the `tui/modals`,
`tui/screens`, and `tui/widgets` UI convention, with colocated styling
and focused state/content modules.

- Supports local, GitHub, Git, and marketplace JSON sources.
- Adds install, enable, disable, uninstall, and safe marketplace removal
through `/plugins` and `dcode plugin`.
- Reloads plugin skills and plugin MCP configuration with `/reload` when
experimental mode is enabled.
- Namespaces plugin skills as `{plugin_id}:{skill_name}` through a
code-local `PluginSkillsMiddleware` adapter, so no SDK changes are
required.

Made by [Open
SWE](https://openswe.vercel.app/agents/019f5dea-0f1f-73fe-9803-32d1b13fbd4c)

---------

Signed-off-by: Johannes du Plessis <johannes@langchain.dev>
Co-authored-by: Alexander Olsen <aolsenjazz@gmail.com>
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: open-swe[bot] <215916821+open-swe[bot]@users.noreply.github.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-07-15 09:11:28 -04:00

46 lines
1.4 KiB
Python

"""Internal JSON normalization helpers."""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from deepagents_code.plugins.models import JsonObject, JsonValue
def json_value(value: object) -> JsonValue | None:
"""Normalize a decoded value to the supported JSON type.
Returns:
The normalized value, or `None` for an unsupported value.
"""
if value is None or isinstance(value, (bool, int, float, str)):
return value
if isinstance(value, list):
normalized: list[JsonValue] = []
for item in value:
converted = json_value(item)
if converted is not None or item is None:
normalized.append(converted)
return normalized
if isinstance(value, dict):
normalized_object: JsonObject = {}
for key, item in value.items():
if not isinstance(key, str):
continue
converted = json_value(item)
if converted is not None or item is None:
normalized_object[key] = converted
return normalized_object
return None
def json_object(value: object) -> JsonObject:
"""Normalize a decoded value to a JSON object.
Returns:
The normalized object, or an empty object for a non-object value.
"""
converted = json_value(value)
return converted if isinstance(converted, dict) else {}