Extract Cortex OS Hermes WebUI Host Adapter
This commit is contained in:
parent
8b6c810f4a
commit
1707a7b09d
@ -2,7 +2,7 @@
|
||||
|
||||
**Upstream version:** v0.51.118
|
||||
**Plugin version:** 0.5.0
|
||||
**Total dependencies:** 61 (40 public API · 0 forced internal · 21 frontend)
|
||||
**Total dependencies:** 62 (41 public API · 0 forced internal · 21 frontend)
|
||||
|
||||
> **Auto-generated by `scripts/ast-connection-map.py`. Do not hand-edit.**
|
||||
> To change a justification, edit the `# CONNECTION:` comment above the
|
||||
@ -14,21 +14,19 @@
|
||||
|
||||
| Plugin location | Upstream symbol | Snippet |
|
||||
|---|---|---|
|
||||
| `plugin.py:29` | `api.logger` | `log = api.logger("svrnty.plugin")` |
|
||||
| `plugin.py:34` | `api.register_static` | `api.register_static(STATIC_PREFIX, str(STATIC_DIR))` |
|
||||
| `plugin.py:35` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/app.css")` |
|
||||
| `plugin.py:36` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/app.js")` |
|
||||
| `plugin.py:39` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/svrnty_nav.js")` |
|
||||
| `plugin.py:42` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/adwright.css")` |
|
||||
| `plugin.py:43` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/adwright.js")` |
|
||||
| `plugin.py:45` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/bte.css")` |
|
||||
| `plugin.py:46` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/bte.js")` |
|
||||
| `plugin.py:48` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/canvas.css")` |
|
||||
| `plugin.py:49` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/canvas.js")` |
|
||||
| `plugin.py:51` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/umbrella_inline.css")` |
|
||||
| `plugin.py:52` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/umbrella_inline.js")` |
|
||||
| `plugin.py:54` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/cortex-os/runtime-health/runtime_health.c` |
|
||||
| `plugin.py:55` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/cortex-os/runtime-health/runtime_health.js")` |
|
||||
| `plugin.py:31` | `api.logger` | `log = api.logger("svrnty.plugin")` |
|
||||
| `plugin.py:36` | `api.register_static` | `api.register_static(STATIC_PREFIX, str(STATIC_DIR))` |
|
||||
| `plugin.py:37` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/app.css")` |
|
||||
| `plugin.py:38` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/app.js")` |
|
||||
| `plugin.py:41` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/svrnty_nav.js")` |
|
||||
| `plugin.py:44` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/adwright.css")` |
|
||||
| `plugin.py:45` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/adwright.js")` |
|
||||
| `plugin.py:47` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/bte.css")` |
|
||||
| `plugin.py:48` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/bte.js")` |
|
||||
| `plugin.py:50` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/canvas.css")` |
|
||||
| `plugin.py:51` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/canvas.js")` |
|
||||
| `plugin.py:53` | `api.inject_stylesheet` | `api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/umbrella_inline.css")` |
|
||||
| `plugin.py:54` | `api.inject_script` | `api.inject_script(f"/plugins/{STATIC_PREFIX}/umbrella_inline.js")` |
|
||||
| `routes/adwright.py:68` | `api.logger` | `log = api.logger("svrnty.routes.adwright")` |
|
||||
| `routes/adwright.py:69` | `api.register_route` | `api.register_route(` |
|
||||
| `routes/adwright.py:71` | `api.register_route` | `api.register_route(` |
|
||||
@ -44,6 +42,9 @@
|
||||
| `routes/canvas.py:57` | `api.register_route` | `api.register_route("/api/canvas/command", "POST", _handle_command)` |
|
||||
| `routes/canvas.py:58` | `api.register_route` | `api.register_route("/api/canvas/design-context", "GET", _handle_design_context)` |
|
||||
| `routes/canvas.py:59` | `api.register_route` | `api.register_route("/api/canvas/events", "GET", _handle_events)` |
|
||||
| `routes/cortex_os_extension.py:17` | `api.logger` | `log = api.logger("svrnty.routes.cortex_os_extension")` |
|
||||
| `routes/cortex_os_extension.py:21` | `api.inject_stylesheet` | `api.inject_stylesheet(stylesheet)` |
|
||||
| `routes/cortex_os_extension.py:22` | `api.inject_script` | `api.inject_script(script)` |
|
||||
| `routes/cortex_os_runtime_health.py:26` | `api.logger` | `log = api.logger("svrnty.routes.cortex_os_runtime_health")` |
|
||||
| `routes/cortex_os_runtime_health.py:27` | `api.register_route` | `api.register_route(ROUTE_PATH, ROUTE_METHOD, _handle_runtime_health)` |
|
||||
| `routes/transcribe.py:37` | `api.logger` | `log = api.logger("svrnty.routes.transcribe")` |
|
||||
|
||||
@ -35,12 +35,14 @@ assets:
|
||||
- /plugins/svrnty/bte.js
|
||||
- /plugins/svrnty/canvas.js
|
||||
- /plugins/svrnty/umbrella_inline.js
|
||||
- /plugins/svrnty/cortex-os/runtime-health/runtime_health.js
|
||||
stylesheets:
|
||||
- /plugins/svrnty/app.css
|
||||
- /plugins/svrnty/adwright.css
|
||||
- /plugins/svrnty/bte.css
|
||||
- /plugins/svrnty/canvas.css
|
||||
- /plugins/svrnty/umbrella_inline.css
|
||||
- /plugins/svrnty/cortex-os/runtime-health/runtime_health.css
|
||||
|
||||
# Routes this plugin registers at load time (declarative cross-check vs runtime).
|
||||
# Each row maps to a routes/<file>.py.
|
||||
@ -59,6 +61,7 @@ routes:
|
||||
- { path: /api/canvas/command, method: POST, file: routes/canvas.py, status: live }
|
||||
- { path: /api/canvas/design-context, method: GET, file: routes/canvas.py, status: seed }
|
||||
- { path: /api/canvas/events, method: GET, file: routes/canvas.py, status: seed }
|
||||
- { path: /api/cortex-os/runtime-health, method: GET, file: routes/cortex_os_extension.py, status: live }
|
||||
|
||||
# Audio-attachment processors (called by streaming.py before agent receives message).
|
||||
audio_processors:
|
||||
|
||||
@ -14,6 +14,8 @@ in `static/`. The map of every upstream dependency is in CONNECTION-MAP.md
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from routes import cortex_os_extension
|
||||
|
||||
# Static + asset URL prefix (per protocol §12, decision Q5: /plugins/svrnty/<asset>)
|
||||
STATIC_PREFIX = "svrnty"
|
||||
STATIC_DIR = Path(__file__).resolve().parent / "static"
|
||||
@ -50,11 +52,11 @@ def register(api):
|
||||
# Inline Umbrella graph for the Hermes Workspace right panel.
|
||||
api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/umbrella_inline.css")
|
||||
api.inject_script(f"/plugins/{STATIC_PREFIX}/umbrella_inline.js")
|
||||
# Cortex OS Runtime Health slice: read-only route status display.
|
||||
api.inject_stylesheet(f"/plugins/{STATIC_PREFIX}/cortex-os/runtime-health/runtime_health.css")
|
||||
api.inject_script(f"/plugins/{STATIC_PREFIX}/cortex-os/runtime-health/runtime_health.js")
|
||||
log.info("static + assets wired at /plugins/%s/", STATIC_PREFIX)
|
||||
|
||||
# Cortex OS Plugin development mount: S23 Runtime Health read-only member.
|
||||
cortex_os_extension.register(api, STATIC_PREFIX)
|
||||
|
||||
# Routes — each feature lives in its own module under routes/.
|
||||
# Phase 2 will populate these. Import-and-register pattern; failures are
|
||||
# logged but don't take down the rest of the plugin.
|
||||
@ -84,5 +86,4 @@ def _phase2_routes():
|
||||
"bte_proxy", # P2.D — BTE Command Center same-origin proxy (PRD §3) ✓
|
||||
"canvas", # Sovereign Stitch-like design canvas proxy + event seed
|
||||
"umbrella", # P2.E — cortex-os umbrella graph viz (UMBRELLA-VIZ-PRD) ✓
|
||||
"cortex_os_runtime_health", # S23.0-I4 — Cortex OS Runtime Health read-only slice ✓
|
||||
]
|
||||
|
||||
30
routes/cortex_os_extension.py
Normal file
30
routes/cortex_os_extension.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""Cortex OS Plugin Hermes WebUI Host Adapter extraction surface."""
|
||||
|
||||
from routes import cortex_os_runtime_health
|
||||
|
||||
PACKAGE_ID = "cortex-os-extension"
|
||||
MEMBER_ID = "s23-runtime-health-read-only-slice"
|
||||
ACTIVE_DEVELOPMENT_MOUNT_TARGET = "hermes-webui"
|
||||
SURFACE_ID = "hermes-webui-host-adapter"
|
||||
RUNTIME_HEALTH_ROUTE = "/api/cortex-os/runtime-health"
|
||||
RUNTIME_HEALTH_METHOD = "GET"
|
||||
RUNTIME_HEALTH_STYLESHEET = "/plugins/{static_prefix}/cortex-os/runtime-health/runtime_health.css"
|
||||
RUNTIME_HEALTH_SCRIPT = "/plugins/{static_prefix}/cortex-os/runtime-health/runtime_health.js"
|
||||
|
||||
|
||||
def register(api, static_prefix):
|
||||
"""Register only the Cortex OS Runtime Health member for Hermes WebUI."""
|
||||
log = api.logger("svrnty.routes.cortex_os_extension")
|
||||
stylesheet = RUNTIME_HEALTH_STYLESHEET.format(static_prefix=static_prefix)
|
||||
script = RUNTIME_HEALTH_SCRIPT.format(static_prefix=static_prefix)
|
||||
|
||||
api.inject_stylesheet(stylesheet)
|
||||
api.inject_script(script)
|
||||
cortex_os_runtime_health.register(api)
|
||||
|
||||
log.info(
|
||||
"cortex-os-extension mounted: %s %s via %s",
|
||||
RUNTIME_HEALTH_METHOD,
|
||||
RUNTIME_HEALTH_ROUTE,
|
||||
SURFACE_ID,
|
||||
)
|
||||
@ -13,6 +13,7 @@ import pytest
|
||||
|
||||
PLUGIN_REPO = Path(__file__).resolve().parents[2]
|
||||
FORK_REPO = PLUGIN_REPO.parent / "hermes-webui"
|
||||
MANIFEST = PLUGIN_REPO / "manifest.yaml"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@ -85,6 +86,15 @@ def test_loader_register_wires_our_plugin(loader, monkeypatch):
|
||||
assert len(loader._AUDIO_PROCESSORS) == 1
|
||||
|
||||
|
||||
def test_manifest_declares_cortex_os_runtime_health_surface():
|
||||
manifest = MANIFEST.read_text(encoding="utf-8")
|
||||
|
||||
assert "/api/cortex-os/runtime-health" in manifest
|
||||
assert "routes/cortex_os_extension.py" in manifest
|
||||
assert "/plugins/svrnty/cortex-os/runtime-health/runtime_health.css" in manifest
|
||||
assert "/plugins/svrnty/cortex-os/runtime-health/runtime_health.js" in manifest
|
||||
|
||||
|
||||
def test_loader_noop_when_env_unset(loader, monkeypatch):
|
||||
"""No env var = no plugin loaded. Upstream behavior fully preserved."""
|
||||
monkeypatch.delenv("HERMES_WEBUI_PYTHON_PLUGIN", raising=False)
|
||||
|
||||
51
tests/unit/test_cortex_os_extension_adapter.py
Normal file
51
tests/unit/test_cortex_os_extension_adapter.py
Normal file
@ -0,0 +1,51 @@
|
||||
from unittest.mock import Mock
|
||||
|
||||
from routes import cortex_os_extension
|
||||
|
||||
|
||||
def test_adapter_constants_preserve_s27_identity():
|
||||
assert cortex_os_extension.PACKAGE_ID == "cortex-os-extension"
|
||||
assert cortex_os_extension.MEMBER_ID == "s23-runtime-health-read-only-slice"
|
||||
assert cortex_os_extension.ACTIVE_DEVELOPMENT_MOUNT_TARGET == "hermes-webui"
|
||||
assert cortex_os_extension.RUNTIME_HEALTH_METHOD == "GET"
|
||||
assert cortex_os_extension.RUNTIME_HEALTH_ROUTE == "/api/cortex-os/runtime-health"
|
||||
|
||||
|
||||
def test_adapter_registers_runtime_health_route_and_assets_only():
|
||||
api = Mock()
|
||||
api.logger.return_value = Mock()
|
||||
|
||||
cortex_os_extension.register(api, "svrnty")
|
||||
|
||||
api.inject_stylesheet.assert_called_once_with(
|
||||
"/plugins/svrnty/cortex-os/runtime-health/runtime_health.css"
|
||||
)
|
||||
api.inject_script.assert_called_once_with(
|
||||
"/plugins/svrnty/cortex-os/runtime-health/runtime_health.js"
|
||||
)
|
||||
api.register_route.assert_called_once()
|
||||
method, path = api.register_route.call_args.args[:2]
|
||||
assert method == "/api/cortex-os/runtime-health"
|
||||
assert path == "GET"
|
||||
api.register_static.assert_not_called()
|
||||
api.config_get.assert_not_called()
|
||||
api.register_audio_attachment_processor.assert_not_called()
|
||||
|
||||
|
||||
def test_adapter_source_has_no_forbidden_runtime_discovery():
|
||||
source = cortex_os_extension.__loader__.get_source(cortex_os_extension.__name__)
|
||||
forbidden = [
|
||||
"glob(",
|
||||
"rglob(",
|
||||
"subprocess",
|
||||
"os.walk",
|
||||
"sot/08-OUTPUTS",
|
||||
"hermes_webui",
|
||||
"hermes_agent",
|
||||
"register_static",
|
||||
"config_get",
|
||||
"register_audio_attachment_processor",
|
||||
"product readiness",
|
||||
]
|
||||
for snippet in forbidden:
|
||||
assert snippet not in source
|
||||
Loading…
Reference in New Issue
Block a user