feat: hub identity and config endpoints (CO1 2.3, 2.4)#50
Conversation
GET /hub/identity returns a stable hub ID, user-configurable display name, and HANA version. The hub ID is a memorable three-word kebab-case identifier (e.g. "bold-crystal-synapse") generated eagerly at startup and persisted to config. POST /hub/identity (auth required) allows updating the display name, which is stripped of whitespace and validated for length. The GET endpoint is intentionally public (no auth) so Nodes can identify a Hub during network discovery.
Reads neon.yaml to expose active TTS and STT plugin names, with known defaults as fallback. LLM hardcoded to "Neon Classic" until BrainForge has a config surface. Gracefully handles missing, malformed, or unreadable neon.yaml for non-Hub deployments.
|
Note on CI failure: The test failure is pre-existing and unrelated to this PR. The import chain is All 45 tests in this PR pass locally in Docker ( |
NeonDaniel
left a comment
There was a problem hiding this comment.
Couple minor suggestions. I still need to deploy and test this before approving
- Replace local LLMConfig with LLMPersona from neon-data-models so the /hub/config response shape matches the rest of the LLM API surface - Add TODO comment in /hub/config noting that the neon.yaml fallback assumes shared local FS with core services; future work should add messagebus handlers (opm.tts.query/opm.stt.query) as an alternative for split deployments
|
RE test failures and container errors, adding |
NeonDaniel
left a comment
There was a problem hiding this comment.
Deployed and tested at hana.neonaialpha.com. Noted a permissions check to implement and some exceptions I ran into that might be handled gracefully
- POST /hub/identity now requires hub: ADMIN permission via RBAC check using PermissionsConfig.from_roles(), matching the pattern used in get_user and node_server endpoints - Gracefully handle read-only filesystem (k8s deployments) when persisting hub_id at startup and display_name on update. Startup logs an error and continues; update returns a warning field so the caller knows the change won't survive a restart - Add HubIdentityResponse.warning field (null when everything is fine) - New test: test_hub_identity_update_insufficient_permissions verifies guest users get 403 on the update endpoint
Fixes the pre-existing CI failure where test_mq_websocket_api.py fails to collect due to ModuleNotFoundError on ovos_utils.signal. The newer neon-utils pins a compatible ovos-utils version.
When node_auth=true, issued tokens get AccessRoles.NODE for all permission fields regardless of the user's actual permissions. This allows Node devices to authenticate as a real user but with limited privileges — they can connect to the websocket and read hub config, but cannot manage users or access admin endpoints. Designed for QR code pairing: the Node scans credentials for a real user account and calls /auth/login with node_auth=true to get appropriately scoped tokens.
Summary
GET /hub/identityreturns a stable, memorable hub ID (e.g.bold-crystal-synapse), user-configurable display name, and software version.POST /hub/identity(auth required) updates the display name. Hub ID is generated once at first boot and persisted to config.GET /hub/configreturns the active TTS, STT, and LLM engine names. TTS/STT are read fromneon.yamlwith known defaults (neon-tts-plugin-coqui,neon-stt-plugin-nemo) as fallback. LLM is hardcoded to "Neon Classic". Gracefully handles missing, malformed, or unreadableneon.yamlfor non-Hub deployments.Files changed
neon_hana/hub_id.py— Docker-style 3-word kebab-case ID generator (new)neon_hana/schema/hub_requests.py— Pydantic v2 request/response models (new)neon_hana/app/routers/hub.py— Hub router with identity + config endpoints (new)neon_hana/app/__init__.py— Register hub routertests/test_hub_id.py— Generator unit tests (new)tests/test_app.py— 16 new endpoint and edge case testsTest plan
GET /hub/identityreturns 200 with non-emptyhub_id,display_name,versionhub_idis stable across requests and container restartsPOST /hub/identitywith valid auth updates display name (whitespace stripped)POST /hub/identitywithout auth returns 401/403GET /hub/configreturns TTS/STT module names from neon.yamlGET /hub/configreturns defaults when neon.yaml has no TTS/STT keysGET /hub/configreturns null TTS/STT when neon.yaml is absentghcr.io/neongeckocom/neon-hana:dev)