fix(resources): remove unsupported executable resource type #3248
@@ -6,6 +6,7 @@ Changed `wf10_batch.robot` to be less likely to create files, and
|
||||
`plan_generation_graph.robot` to give more test answers.
|
||||
|
||||
## [Unreleased]
|
||||
- **fix(resources): remove unsupported executable resource type and fix resource list columns** (#3077 / PR #3248): Removed `executable` from `LSP_RESOURCE_TYPES` and `BUILTIN_TYPE_NAMES` (the specification defines no such built-in type). Updated `agents resource list` CLI table columns from `[ID, Name, Type, Status, Kind, Location, Description]` to the spec-required `[Name, ID, Type, Phys/Virt, Children, Projects]`. Deleted orphaned `examples/resource-types/executable.yaml`. Lifecycle state for container resources is now displayed as a note below the resource table.
|
||||
- **fix(cli): add Read-Only and Writes columns to tool list output** (#1476): Rewrote
|
||||
`list_tools()` in `src/cleveragents/cli/commands/tool.py` to render exactly the 5
|
||||
spec-required columns (Name, Type, Source, Read-Only, Writes), removed the legacy
|
||||
|
||||
@@ -55,3 +55,4 @@ Below are some of the specific details of various contributions.
|
||||
dropped. Includes Behave BDD and Robot Framework regression tests.
|
||||
* HAL 9000 has contributed the config-actor combined-format support fix (PR #11232 / issue #11189): added ``_detect_nested_config_actor()``, ``_flatten_config_actor()``, and handling in ``ActorConfiguration.from_blob()`` to transparently flatten the nested ``config.actor`` block from both compact-string and nested-dict forms so v3 detection, schema validation, and canonicalisation see flat data — eliminating the ``"provider is required"`` crash.
|
||||
* HAL 9000 has contributed the actor compiler `actor_ref` field fix (issue #1429): corrected `_map_node()` and `compile_actor()` in `src/cleveragents/actor/compiler.py` to read `actor_ref` from the top-level `NodeDefinition.actor_ref` field instead of `node.config.get("actor_ref")`, resolving silent failures on all SUBGRAPH nodes where `subgraph_refs` was always empty and `NodeConfig.subgraph` was always `None`.
|
||||
* HAL 9000 has contributed the removal of the unsupported executable resource type (PR #3248 / issue #3077): removed `executable` from `LSP_RESOURCE_TYPES` and `BUILTIN_TYPE_NAMES`, updated `agents resource list` CLI table columns to the spec-required `[Name, ID, Type, Phys/Virt, Children, Projects]`, deleted orphaned `examples/resource-types/executable.yaml`, and updated related BDD test coverage.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# Spec reference: docs/adr/ADR-039-container-resource-types.md lines 207-226
|
||||
schema_version: "1.0"
|
||||
name: executable
|
||||
description: "System executable (language runtime, compiler, LSP server binary). Discovered from container or host PATH."
|
||||
resource_kind: physical
|
||||
sandbox_strategy: none
|
||||
user_addable: true
|
||||
built_in: true
|
||||
cli_args:
|
||||
- name: path
|
||||
type: string
|
||||
required: true
|
||||
description: Absolute path to the executable
|
||||
- name: version
|
||||
type: string
|
||||
required: false
|
||||
description: Executable version if detectable
|
||||
parent_types: ["container-exec-env", "fs-directory"]
|
||||
child_types: []
|
||||
handler: "cleveragents.resource.handlers.executable:ExecutableHandler"
|
||||
auto_discovery:
|
||||
trigger_types: ["container-exec-env", "fs-directory"]
|
||||
scan_paths: []
|
||||
lazy: true
|
||||
capabilities:
|
||||
read: true
|
||||
write: false
|
||||
sandbox: false
|
||||
checkpoint: false
|
||||
@@ -102,6 +102,14 @@ Feature: Resource CLI commands
|
||||
When I run resource list with format "json"
|
||||
Then the resource output should be valid JSON
|
||||
|
||||
Scenario: List resources shows spec-required columns
|
||||
Given built-in types are bootstrapped
|
||||
And I run resource add "git-checkout" "local/col-test" with path "/tmp/ctest"
|
||||
When I run resource list
|
||||
Then the resource output should contain "Phys/Virt"
|
||||
And the resource output should contain "Children"
|
||||
And the resource output should contain "Projects"
|
||||
|
||||
# ---- Resource Show ----
|
||||
|
||||
Scenario: Show a resource by name
|
||||
|
||||
@@ -7,10 +7,12 @@ Feature: agents resource list shows devcontainer lifecycle state column
|
||||
Given a fresh in-memory resource registry
|
||||
And built-in types are bootstrapped
|
||||
|
||||
Scenario: resource list shows "Status" column header
|
||||
Scenario: resource list shows spec-required column headers
|
||||
Given a devcontainer-instance resource is registered
|
||||
When I run resource list with all flag
|
||||
Then the resource output should contain "Status"
|
||||
Then the resource output should contain "Phys/Virt"
|
||||
And the resource output should contain "Children"
|
||||
And the resource output should contain "Projects"
|
||||
|
||||
Scenario: resource list shows "detected (not built)" for a new devcontainer-instance
|
||||
Given a devcontainer-instance resource is registered
|
||||
@@ -68,8 +70,7 @@ Feature: agents resource list shows devcontainer lifecycle state column
|
||||
Scenario: resource list shows lifecycle state for container-instance resources
|
||||
Given a container-instance resource is registered
|
||||
When I run resource list with all flag
|
||||
Then the resource output should contain "Status"
|
||||
And the resource output should contain "detected (not built)"
|
||||
Then the resource output should contain "detected (not built)"
|
||||
|
||||
Scenario: resource list succeeds gracefully when lifecycle tracker raises an error
|
||||
Given a devcontainer-instance resource is registered
|
||||
|
||||
@@ -16,18 +16,12 @@ Feature: LSP Resource Types
|
||||
|
||||
Examples:
|
||||
| type_name |
|
||||
| executable |
|
||||
| lsp-server |
|
||||
| lsp-workspace |
|
||||
| lsp-document |
|
||||
|
||||
# ── User-addable flags ────────────────────────────────────────
|
||||
|
||||
Scenario: executable is user-addable for lsp_rt
|
||||
Given the built-in executable YAML file for lsp_rt
|
||||
When I load the YAML via schema for lsp_rt
|
||||
Then the lsp_rt schema user_addable should be true
|
||||
|
||||
Scenario: lsp-server is user-addable for lsp_rt
|
||||
Given the built-in lsp-server YAML file for lsp_rt
|
||||
When I load the YAML via schema for lsp_rt
|
||||
@@ -51,12 +45,6 @@ Feature: LSP Resource Types
|
||||
Then the lsp_rt capability read should be true
|
||||
And the lsp_rt capability write should be true
|
||||
|
||||
Scenario: executable has read-only capabilities for lsp_rt
|
||||
Given the built-in executable YAML file for lsp_rt
|
||||
When I load the YAML via schema for lsp_rt
|
||||
Then the lsp_rt capability read should be true
|
||||
And the lsp_rt capability write should be false
|
||||
|
||||
# ── Parent/child hierarchy ────────────────────────────────────
|
||||
|
||||
Scenario: lsp-server has lsp-workspace as child type for lsp_rt
|
||||
@@ -81,12 +69,6 @@ Feature: LSP Resource Types
|
||||
|
||||
# ── Auto-discovery ────────────────────────────────────────────
|
||||
|
||||
Scenario: executable has auto-discovery from container-exec-env for lsp_rt
|
||||
Given the built-in executable YAML file for lsp_rt
|
||||
When I load the YAML via schema for lsp_rt
|
||||
Then the lsp_rt auto_discovery should be present
|
||||
And the lsp_rt auto_discovery trigger_types should contain "container-exec-env"
|
||||
|
||||
Scenario: lsp-workspace has auto-discovery from lsp-server for lsp_rt
|
||||
Given the built-in lsp-workspace YAML file for lsp_rt
|
||||
When I load the YAML via schema for lsp_rt
|
||||
@@ -97,8 +79,7 @@ Feature: LSP Resource Types
|
||||
|
||||
Scenario: BUILTIN_NAMES includes all LSP types for lsp_rt
|
||||
Given the ResourceTypeSpec BUILTIN_NAMES set for lsp_rt
|
||||
Then BUILTIN_NAMES should contain "executable" for lsp_rt
|
||||
And BUILTIN_NAMES should contain "lsp-server" for lsp_rt
|
||||
Then BUILTIN_NAMES should contain "lsp-server" for lsp_rt
|
||||
And BUILTIN_NAMES should contain "lsp-workspace" for lsp_rt
|
||||
And BUILTIN_NAMES should contain "lsp-document" for lsp_rt
|
||||
|
||||
@@ -106,9 +87,6 @@ Feature: LSP Resource Types
|
||||
|
||||
Scenario: LSP types survive DB roundtrip after bootstrap for lsp_rt
|
||||
Given a lsp_rt fresh in-memory resource registry with bootstrap
|
||||
When I query the lsp_rt registry for type "executable"
|
||||
Then the lsp_rt db type "executable" should exist
|
||||
And the lsp_rt db type "executable" should have kind "physical"
|
||||
When I query the lsp_rt registry for type "lsp-server"
|
||||
Then the lsp_rt db type "lsp-server" should exist
|
||||
When I query the lsp_rt registry for type "lsp-workspace"
|
||||
|
||||
@@ -15,26 +15,30 @@ def _import_lsp_types() -> None:
|
||||
LSP_RESOURCE_TYPES,
|
||||
)
|
||||
|
||||
assert len(LSP_RESOURCE_TYPES) == 4, f"Expected 4, got {len(LSP_RESOURCE_TYPES)}"
|
||||
assert len(LSP_RESOURCE_TYPES) == 3, f"Expected 3, got {len(LSP_RESOURCE_TYPES)}"
|
||||
names = [t["name"] for t in LSP_RESOURCE_TYPES]
|
||||
for expected in ("executable", "lsp-server", "lsp-workspace", "lsp-document"):
|
||||
for expected in ("lsp-server", "lsp-workspace", "lsp-document"):
|
||||
assert expected in names, f"{expected} not in LSP_RESOURCE_TYPES: {names}"
|
||||
|
||||
print("import-lsp-types-ok")
|
||||
|
||||
|
||||
def _check_builtin_names() -> None:
|
||||
"""Verify all 4 LSP types are in BUILTIN_NAMES."""
|
||||
"""Verify all 3 LSP types are in BUILTIN_NAMES."""
|
||||
from cleveragents.domain.models.core.resource_type import ResourceTypeSpec
|
||||
|
||||
for name in ("executable", "lsp-server", "lsp-workspace", "lsp-document"):
|
||||
for name in ("lsp-server", "lsp-workspace", "lsp-document"):
|
||||
assert name in ResourceTypeSpec.BUILTIN_NAMES, f"{name} not in BUILTIN_NAMES"
|
||||
|
||||
assert "executable" not in ResourceTypeSpec.BUILTIN_NAMES, (
|
||||
"executable should not be in BUILTIN_NAMES (not a spec-defined type)"
|
||||
)
|
||||
|
||||
print("check-builtin-names-ok")
|
||||
|
||||
|
||||
def _db_roundtrip() -> None:
|
||||
"""Bootstrap in-memory DB and verify all 4 LSP types are retrievable."""
|
||||
"""Bootstrap in-memory DB and verify all 3 LSP types are retrievable."""
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
@@ -48,7 +52,7 @@ def _db_roundtrip() -> None:
|
||||
factory = sessionmaker(bind=engine, expire_on_commit=False)
|
||||
svc = ResourceRegistryService(session_factory=factory)
|
||||
|
||||
for name in ("executable", "lsp-server", "lsp-workspace", "lsp-document"):
|
||||
for name in ("lsp-server", "lsp-workspace", "lsp-document"):
|
||||
spec = svc.show_type(name)
|
||||
assert spec is not None, f"{name} not found after bootstrap"
|
||||
assert str(spec.resource_kind) == "physical", (
|
||||
@@ -85,32 +89,27 @@ def _check_hierarchy() -> None:
|
||||
assert "lsp-workspace" in types["lsp-document"]["parent_types"], (
|
||||
"lsp-document missing lsp-workspace parent"
|
||||
)
|
||||
# executable has no children
|
||||
assert types["executable"]["child_types"] == [], (
|
||||
"executable should have no children"
|
||||
)
|
||||
|
||||
print("check-hierarchy-ok")
|
||||
|
||||
|
||||
def _check_auto_discovery() -> None:
|
||||
"""Verify executable has auto_discovery with trigger_types."""
|
||||
"""Verify lsp-workspace has auto_discovery with trigger_types."""
|
||||
from cleveragents.application.services._resource_registry_lsp import (
|
||||
LSP_RESOURCE_TYPES,
|
||||
)
|
||||
|
||||
types = {t["name"]: t for t in LSP_RESOURCE_TYPES}
|
||||
types = {t["name"] for t in LSP_RESOURCE_TYPES}
|
||||
|
||||
# executable has auto_discovery
|
||||
ad = types["executable"].get("auto_discovery")
|
||||
assert ad is not None, "executable missing auto_discovery"
|
||||
assert "container-exec-env" in ad.get("trigger_types", []), (
|
||||
"executable missing container-exec-env trigger"
|
||||
# executable should not be present
|
||||
assert "executable" not in types, (
|
||||
"executable should not be in LSP_RESOURCE_TYPES (not a spec-defined type)"
|
||||
)
|
||||
assert ad.get("lazy") is True, "executable auto_discovery should be lazy"
|
||||
|
||||
lsp_types = {t["name"]: t for t in LSP_RESOURCE_TYPES}
|
||||
|
||||
# lsp-workspace has auto_discovery from lsp-server
|
||||
ad_ws = types["lsp-workspace"].get("auto_discovery")
|
||||
ad_ws = lsp_types["lsp-workspace"].get("auto_discovery")
|
||||
assert ad_ws is not None, "lsp-workspace missing auto_discovery"
|
||||
assert "lsp-server" in ad_ws.get("trigger_types", []), (
|
||||
"lsp-workspace missing lsp-server trigger"
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
"""LSP resource type definitions for the Resource Registry.
|
||||
|
||||
Contains the built-in LSP-related type entries (``executable``,
|
||||
``lsp-server``, ``lsp-workspace``, ``lsp-document``) that are appended
|
||||
to ``BUILTIN_TYPES`` in ``_resource_registry_data``.
|
||||
Contains the built-in LSP-related type entries (``lsp-server``,
|
||||
``lsp-workspace``, ``lsp-document``) that are appended to
|
||||
``BUILTIN_TYPES`` in ``_resource_registry_data``.
|
||||
|
||||
These types bridge the resource system with the LSP runtime, allowing
|
||||
actors to discover available language tooling and the LSP system to know
|
||||
which resources it operates on.
|
||||
|
||||
Spec reference: docs/adr/ADR-039-container-resource-types.md (executable),
|
||||
docs/adr/ADR-040-lsp-resource-types.md (lsp-server,
|
||||
Spec reference: docs/adr/ADR-040-lsp-resource-types.md (lsp-server,
|
||||
lsp-workspace, lsp-document)
|
||||
|
||||
.. note::
|
||||
@@ -28,52 +27,11 @@ __all__ = ["LSP_RESOURCE_TYPES"]
|
||||
# === LSP Resource Types (#832) ===
|
||||
#
|
||||
# These types model language tooling infrastructure in the resource DAG.
|
||||
# - executable: system binary / interpreter / LSP server binary
|
||||
# - lsp-server: a configured or running LSP server instance
|
||||
# - lsp-workspace: workspace root tracked by an LSP server
|
||||
# - lsp-document: text document tracked by an LSP server
|
||||
|
||||
LSP_RESOURCE_TYPES: list[dict[str, Any]] = [
|
||||
# ── executable ───────────────────────────────────────────────
|
||||
{
|
||||
"name": "executable",
|
||||
"description": (
|
||||
"System executable (language runtime, compiler, LSP server "
|
||||
"binary). Discovered from container or host PATH."
|
||||
),
|
||||
"resource_kind": "physical",
|
||||
"sandbox_strategy": "none",
|
||||
"user_addable": True,
|
||||
"built_in": True,
|
||||
"cli_args": [
|
||||
{
|
||||
"name": "path",
|
||||
"type": "string",
|
||||
"required": True,
|
||||
"description": "Absolute path to the executable",
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"type": "string",
|
||||
"required": False,
|
||||
"description": "Executable version if detectable",
|
||||
},
|
||||
],
|
||||
"parent_types": ["container-exec-env", "fs-directory"],
|
||||
"child_types": [],
|
||||
"handler": "cleveragents.resource.handlers.executable:ExecutableHandler",
|
||||
"auto_discovery": {
|
||||
"trigger_types": ["container-exec-env", "fs-directory"],
|
||||
"scan_paths": [],
|
||||
"lazy": True,
|
||||
},
|
||||
"capabilities": {
|
||||
"read": True,
|
||||
"write": False,
|
||||
"sandbox": False,
|
||||
"checkpoint": False,
|
||||
},
|
||||
},
|
||||
# ── lsp-server ───────────────────────────────────────────────
|
||||
{
|
||||
"name": "lsp-server",
|
||||
|
||||
@@ -860,37 +860,40 @@ def resource_list(
|
||||
return
|
||||
|
||||
table = Table(title=f"Resources ({len(resources)} total)")
|
||||
table.add_column("ID", style="dim")
|
||||
table.add_column("Name", style="cyan")
|
||||
table.add_column("ID", style="dim")
|
||||
table.add_column("Type", style="blue")
|
||||
table.add_column("Status", style="yellow")
|
||||
table.add_column("Kind", style="magenta")
|
||||
table.add_column("Location", style="dim")
|
||||
table.add_column("Description", style="dim")
|
||||
table.add_column("Phys/Virt", style="magenta")
|
||||
table.add_column("Children", justify="right")
|
||||
table.add_column("Projects", justify="right")
|
||||
|
||||
detected_devcontainers: list[Any] = []
|
||||
lifecycle_states: list[tuple[Any, str]] = []
|
||||
for res in resources:
|
||||
desc = res.description or ""
|
||||
if len(desc) > 40:
|
||||
desc = desc[:37] + "..."
|
||||
res_id = res.resource_id
|
||||
if len(res_id) > 12:
|
||||
res_id = res_id[:12] + "..."
|
||||
lifecycle_state = _get_lifecycle_state_str(res)
|
||||
if lifecycle_state == "detected (not built)":
|
||||
detected_devcontainers.append(res)
|
||||
if lifecycle_state:
|
||||
lifecycle_states.append((res, lifecycle_state))
|
||||
table.add_row(
|
||||
res_id,
|
||||
res.name or "(unnamed)",
|
||||
res_id,
|
||||
res.resource_type_name,
|
||||
lifecycle_state or "",
|
||||
str(res.classification),
|
||||
res.location or "",
|
||||
desc,
|
||||
str(len(res.children)),
|
||||
str(len(res.linked_projects)),
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
for res, state in lifecycle_states:
|
||||
style = "yellow" if state in ("detected (not built)", "failed") else "blue"
|
||||
label = res.name or res.resource_id
|
||||
console.print(f"[{style}] {label}: {state}[/{style}]")
|
||||
|
||||
for res in detected_devcontainers:
|
||||
location = res.location or "(unknown path)"
|
||||
devcontainer_json = f"{location}/.devcontainer/devcontainer.json"
|
||||
|
||||
@@ -125,7 +125,6 @@ BUILTIN_TYPE_NAMES: frozenset[str] = frozenset(
|
||||
"submodule",
|
||||
"symlink",
|
||||
# LSP resource types (#832)
|
||||
"executable",
|
||||
"lsp-server",
|
||||
"lsp-workspace",
|
||||
"lsp-document",
|
||||
|
||||
Reference in New Issue
Block a user