|
@@ -1,80 +1,61 @@
|
|
|
-# Garden Layer helper module
|
|
|
|
|
|
|
+# Garden Layer
|
|
|
|
|
|
|
|
-The garden layer sits on top of `virtuoso_mcp`. It knows your garden-specific URIs (cycles, clone roots, seed products) but delegates every SPARQL/insert/discovery call to the MCP helpers.
|
|
|
|
|
|
|
+Garden-domain helpers and plugin tools for `virtuoso_mcp`.
|
|
|
|
|
|
|
|
-## Structure
|
|
|
|
|
-
|
|
|
|
|
-- `config.py` loads `.env` values and exposes the Garden URIs (seed product, cycle `2026-3`, clone property, etc.).
|
|
|
|
|
-- `helpers.py` defines `GardenLayer`, which wraps MCP tools such as `insert_triple`, `traverse_property`, and ontology discovery into domain actions (`add_seedling`, `traverse`).
|
|
|
|
|
-
|
|
|
|
|
-## Domain helpers
|
|
|
|
|
|
|
+## Current role
|
|
|
|
|
|
|
|
-`GardenLayer` now exposes these convenience methods:
|
|
|
|
|
|
|
+- Provides domain workflows (cycles, clones, seedlings).
|
|
|
|
|
+- Keeps domain logic separate from generic Virtuoso MCP tools.
|
|
|
|
|
+- Registers `garden_*` plugin tools into `virtuoso_mcp` via `register_layer(...)`.
|
|
|
|
|
|
|
|
-- `describe_subject(subject_uri, limit=10)` – returns predicates/objects (with labels) for a given node.
|
|
|
|
|
-- `path_traverse(subject_uri, property_path, direction="outgoing", limit=10)` – walks a property sequence from the subject and returns each step’s bindings.
|
|
|
|
|
-- `property_usage_statistics(property_uri, examples_limit=5)` – reports how often a property is used and includes sample subjects/objects.
|
|
|
|
|
-- `batch_insert(ttl, graph=None)` – pushes a TTL snippet (or multiple triples via TTL) into the chosen graph in a single request.
|
|
|
|
|
-- `load_examples(files=None, graph=None)` – loads TTL fixtures from `garden_layer/examples/` via the `garden_load_examples` tool (guarded by `MCP_ALLOW_EXAMPLE_LOAD`).
|
|
|
|
|
|
|
+## Current garden tool surface (trimmed)
|
|
|
|
|
|
|
|
-These helpers keep domain code focused on planned workflows while still leveraging the generic MCP toolset.
|
|
|
|
|
|
|
+Only domain-unique prefixed tools are exposed:
|
|
|
|
|
|
|
|
-## Architectural split
|
|
|
|
|
|
|
+- `garden_add_seedling`
|
|
|
|
|
+- `garden_cycle_plants`
|
|
|
|
|
+- `garden_latest_cycle_by_dates`
|
|
|
|
|
+- `garden_clone_to`
|
|
|
|
|
+- `garden_cycle_list_detailed`
|
|
|
|
|
+- `garden_reassign_cycle`
|
|
|
|
|
|
|
|
-- `virtuoso_mcp` owns **generic** capabilities: query guardrails, traversal, ontology/class/property discovery.
|
|
|
|
|
-- `garden_layer` owns **domain workflows**: breeding lifecycle helpers, documentation flows, trait-specific routines.
|
|
|
|
|
|
|
+Redundant prefixed aliases of generic tools were intentionally removed.
|
|
|
|
|
|
|
|
-This split allows additional specialized layers to reuse the same generic ontology tooling without copy/paste.
|
|
|
|
|
|
|
+## Runtime coupling
|
|
|
|
|
|
|
|
-### Example fixtures
|
|
|
|
|
|
|
+- Default endpoint for direct helper calls: `GARDEN_MCP_URL=http://127.0.0.1:8501/rpc`
|
|
|
|
|
+- This uses the compatibility router in `virtuoso_mcp` for simple tool invocation during migration.
|
|
|
|
|
|
|
|
-The domain-specific `examples/` directory now lives inside this package. The MCP exposes a `garden_load_examples` helper so you can insert those fixtures through `/mcp` (just set `MCP_ALLOW_EXAMPLE_LOAD=true` first). The loader calls `garden_layer.examples/*.ttl` and inserts them into the `GARDEN_EXAMPLE_GRAPH` (defaulting to `GRAPH`), which is useful for reproducible tests or for warming up the data set before running higher-level helpers.
|
|
|
|
|
-
|
|
|
|
|
-## Example
|
|
|
|
|
|
|
+## Structure
|
|
|
|
|
|
|
|
-```python
|
|
|
|
|
-from garden_layer import GardenLayer
|
|
|
|
|
-from garden_layer.config import SEED_PRODUCT, CYCLE_2026_3
|
|
|
|
|
|
|
+- `src/garden_layer/domain_tools.py` — domain-native logic
|
|
|
|
|
+- `src/garden_layer/__init__.py` — plugin registration and schemas
|
|
|
|
|
+- `src/garden_layer/helpers.py` — convenience class for direct usage
|
|
|
|
|
+- `test_garden_layer.py` — integration-style tests against running `virtuoso_mcp`
|
|
|
|
|
|
|
|
-garden = GardenLayer()
|
|
|
|
|
-garden.add_seedling(
|
|
|
|
|
- plant_uri="http://world.eu.org/example1#Plant_cookie_kerosene_2027",
|
|
|
|
|
- seed_product_uri=SEED_PRODUCT,
|
|
|
|
|
- cycle_uri=CYCLE_2026_3,
|
|
|
|
|
- label="Cookie x Kerosene 2027",
|
|
|
|
|
-)
|
|
|
|
|
-```
|
|
|
|
|
|
|
+## Tests
|
|
|
|
|
|
|
|
-## Testing
|
|
|
|
|
|
|
+```bash
|
|
|
|
|
+./test.sh
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-`garden_layer/test_garden_layer.py` exercises the garden helpers (`traverse`, `describe_subject`, `path_traverse`, `property_usage_statistics`, and `batch_insert`) against a running MCP server. The suite now also posts directly to the `garden_*` MCP tools (e.g., `garden_describe_subject` and `garden_property_usage_statistics`) to confirm the server endpoint is registered and returns expected bindings. Start the MCP service (`./virtuoso_mcp/run.sh` or `./restart.sh`) before running the tests and invoke them with `python3 -m pytest garden_layer/test_garden_layer.py`. If `pytest` is not installed, install it inside a virtual environment (e.g., `python3 -m venv .env && .env/bin/pip install pytest`).
|
|
|
|
|
|
|
+`test.sh` is self-contained:
|
|
|
|
|
+- activates local `.venv` when present
|
|
|
|
|
+- installs missing test deps if needed
|
|
|
|
|
+- runs pytest with `PYTHONPATH=src`
|
|
|
|
|
|
|
|
-## Installation & usage
|
|
|
|
|
|
|
+Expected result depends on fixture availability; current baseline is passing core domain/plugin checks with optional data-dependent skips.
|
|
|
|
|
|
|
|
-1. Publish the `garden_layer` repo to your private git server (e.g., `https://repo.home.world.eu.org/lucky/garden_layer.git`).
|
|
|
|
|
-2. Install it inside the MCP host environment:
|
|
|
|
|
- ```bash
|
|
|
|
|
- pip install --upgrade git+https://repo.home.world.eu.org/lucky/garden_layer.git
|
|
|
|
|
- ```
|
|
|
|
|
- The package can be uninstalled later with `pip uninstall garden-layer`.
|
|
|
|
|
-3. Restart the MCP server so it picks up the new helpers (our `restart.sh` already calls `killserver.sh` before `run.sh`):
|
|
|
|
|
- ```bash
|
|
|
|
|
- cd /home/lucky/.openclaw/workspace/virtuoso_mcp
|
|
|
|
|
- ./restart.sh
|
|
|
|
|
- ```
|
|
|
|
|
-4. Re-run the garden-layer suite with `GARDEN_LAYER_VENV` pointing at whatever virtualenv you want to use (our example venv lives at `garden_layer/.venv`):
|
|
|
|
|
- ```bash
|
|
|
|
|
- cd /home/lucky/.openclaw/workspace/garden_layer
|
|
|
|
|
- GARDEN_LAYER_VENV="$PWD/.venv" ./test.sh
|
|
|
|
|
- ```
|
|
|
|
|
|
|
+## Install (plugin host)
|
|
|
|
|
|
|
|
-Once the package is installed you can import `garden_layer.GardenLayer` from your own MCP host code (or use it in agents) to orchestrate the domain helpers; building additional `/mcp` endpoints that simply call `GardenLayer` keeps your plugins reusable and the core MCP server generic.
|
|
|
|
|
|
|
+```bash
|
|
|
|
|
+pip install --upgrade git+https://repo.home.world.eu.org/lucky/garden_layer.git
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-## MCP tools exposed by the garden layer
|
|
|
|
|
|
|
+Then in `virtuoso_mcp` set:
|
|
|
|
|
|
|
|
-In addition to the garden layer’s helper-oriented API, the MCP server registers these `garden_*` tools via `DOMAIN_LAYERS`:
|
|
|
|
|
|
|
+```bash
|
|
|
|
|
+DOMAIN_LAYERS=garden_layer.plugin
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-- `garden_latest_cycle_by_dates` — resolve the latest `ProductionCycle` by `productionStartDate` / `productionEndDate`
|
|
|
|
|
-- `garden_cycle_plants` — list plants assigned to a cycle via `inCycle`
|
|
|
|
|
-- `garden_cycle_list_detailed` — detailed cycle listing including clone lineage, strain label/description, gender, and clone siblings
|
|
|
|
|
-- `garden_clone_to` — create a new plant clone by label, copy mother triples (except label/inCycle/cloneOf), set `cloneOf` + `inCycle`
|
|
|
|
|
|
|
+and restart the server.
|