feat: expose Workspace-scoped rotating plugin debug keys (#2395)

* feat: add Workspace-scoped rotating plugin debug tokens

* chore: pin formatted Workspace debug runtime

* chore: pin merged Workspace debug runtime

* chore: pin tenant-safe debug runtime

---------

Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
This commit is contained in:
Hyu
2026-08-04 19:20:06 +08:00
committed by GitHub
parent c08bfc8ced
commit d78546967c
20 changed files with 3713 additions and 3659 deletions
@@ -392,8 +392,8 @@ class PluginsRouterGroup(group.RouterGroup):
)
async def _(request_context: RequestContext) -> str:
"""Get plugin debug information including debug URL and key"""
await self._require_authenticated_plugin_runtime_context(request_context)
debug_info = await self.ap.plugin_connector.get_debug_info()
execution_context = await self._require_authenticated_plugin_runtime_context(request_context)
debug_info = await self.ap.plugin_connector.get_debug_info(execution_context)
# Get debug URL from config
plugin_config = self.ap.instance_config.data.get('plugin', {})
@@ -403,6 +403,7 @@ class PluginsRouterGroup(group.RouterGroup):
data={
'debug_url': debug_url,
'plugin_debug_key': debug_info.get('plugin_debug_key', ''),
'expires_at': debug_info.get('expires_at', ''),
}
)
+4 -2
View File
@@ -251,6 +251,8 @@ class PluginRuntimeConnector(ManagedRuntimeConnector):
def _control_headers(self, *, allow_generate: bool) -> dict[str, str]:
if not self._control_token and allow_generate:
self._control_token = secrets.token_urlsafe(48)
if not self._control_token:
return {}
try:
self._control_token = validate_runtime_secret(
self._control_token,
@@ -1968,11 +1970,11 @@ class PluginRuntimeConnector(ManagedRuntimeConnector):
with runtime_handler.installation_scope(binding):
return await runtime_handler.handle_page_api(plugin_author, plugin_name, page_id, endpoint, method, body)
async def get_debug_info(self) -> dict[str, Any]:
async def get_debug_info(self, execution_context: ExecutionContext) -> dict[str, Any]:
"""Get debug information including debug key and WS URL"""
if not self.is_enable_plugin or not self._runtime_available():
return {}
return await self._runtime_handler().get_debug_info()
return await self._runtime_handler().get_debug_info(execution_context)
async def emit_event(
self,
+7 -7
View File
@@ -1960,14 +1960,14 @@ class RuntimeConnectionHandler(handler.Handler):
)
return result
async def get_debug_info(self) -> dict[str, Any]:
async def get_debug_info(self, execution_context: ExecutionContext) -> dict[str, Any]:
"""Get debug information including debug key and WS URL"""
with self.installation_scope(None):
result = await self.call_action(
LangBotToRuntimeAction.GET_DEBUG_INFO,
{},
timeout=10,
)
result = await self.call_action(
LangBotToRuntimeAction.GET_DEBUG_INFO,
{},
timeout=10,
action_context=execution_context,
)
return result
# ================= RAG Capability Callers (LangBot -> Runtime) =================