mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-17 09:56:06 +00:00
feat(agent-runner): enforce 4.x host-owned execution
This commit is contained in:
@@ -32,6 +32,7 @@ class TestHandlerQueryVariables:
|
||||
|
||||
app.logger = SimpleNamespace()
|
||||
app.logger.debug = MagicMock()
|
||||
app.logger.warning = MagicMock()
|
||||
|
||||
return app
|
||||
|
||||
@@ -71,6 +72,90 @@ class TestHandlerQueryVariables:
|
||||
assert response.code == 0
|
||||
assert mock_query.variables['test_var'] == 'test_value'
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
'key',
|
||||
[
|
||||
'_host_box_scope',
|
||||
'_host_tool_source_refs',
|
||||
'_pipeline_bound_plugins',
|
||||
'_pipeline_bound_mcp_servers',
|
||||
'_pipeline_bound_skills',
|
||||
'_pipeline_mcp_resource_attachments',
|
||||
'_pipeline_mcp_resource_agent_read_enabled',
|
||||
'_activated_skills',
|
||||
'_fallback_model_uuids',
|
||||
'_monitoring_message_id',
|
||||
'_sandbox_outbound_collected',
|
||||
'_authorized_models',
|
||||
'_permission_tools',
|
||||
'_routed_by_rule',
|
||||
],
|
||||
)
|
||||
async def test_set_query_var_rejects_host_reserved_keys(self, mock_app, key):
|
||||
runtime_handler = make_handler(mock_app)
|
||||
original_variables = {key: 'host-owned'}
|
||||
mock_query = SimpleNamespace(variables=original_variables.copy())
|
||||
mock_app.query_pool.cached_queries['test-query'] = mock_query
|
||||
|
||||
response = await runtime_handler.actions[PluginToRuntimeAction.SET_QUERY_VAR.value](
|
||||
{
|
||||
'query_id': 'test-query',
|
||||
'key': key,
|
||||
'value': 'plugin-overwrite',
|
||||
}
|
||||
)
|
||||
|
||||
assert response.code != 0
|
||||
assert response.message == f'Query variable {key!r} is reserved for LangBot Host'
|
||||
assert mock_query.variables == original_variables
|
||||
mock_app.logger.warning.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
'key',
|
||||
[
|
||||
'business_context',
|
||||
'_ltm_context',
|
||||
'_knowledge_base_uuids',
|
||||
'_skill_authoring_post_response_candidate',
|
||||
],
|
||||
)
|
||||
async def test_set_query_var_keeps_plugin_business_variables_writable(self, mock_app, key):
|
||||
runtime_handler = make_handler(mock_app)
|
||||
mock_query = SimpleNamespace(variables={})
|
||||
mock_app.query_pool.cached_queries['test-query'] = mock_query
|
||||
|
||||
response = await runtime_handler.actions[PluginToRuntimeAction.SET_QUERY_VAR.value](
|
||||
{
|
||||
'query_id': 'test-query',
|
||||
'key': key,
|
||||
'value': {'plugin': 'value'},
|
||||
}
|
||||
)
|
||||
|
||||
assert response.code == 0
|
||||
assert mock_query.variables[key] == {'plugin': 'value'}
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize('key', ['', None, 7])
|
||||
async def test_set_query_var_rejects_invalid_key_shapes(self, mock_app, key):
|
||||
runtime_handler = make_handler(mock_app)
|
||||
mock_query = SimpleNamespace(variables={})
|
||||
mock_app.query_pool.cached_queries['test-query'] = mock_query
|
||||
|
||||
response = await runtime_handler.actions[PluginToRuntimeAction.SET_QUERY_VAR.value](
|
||||
{
|
||||
'query_id': 'test-query',
|
||||
'key': key,
|
||||
'value': 'value',
|
||||
}
|
||||
)
|
||||
|
||||
assert response.code != 0
|
||||
assert response.message == 'Query variable key must be a non-empty string'
|
||||
assert mock_query.variables == {}
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_query_var_success(self, mock_app):
|
||||
"""Test get_query_var retrieves variable from query."""
|
||||
@@ -205,10 +290,3 @@ class TestConstantsSemanticVersion:
|
||||
|
||||
assert hasattr(constants, 'edition')
|
||||
assert constants.edition == 'community'
|
||||
|
||||
def test_required_database_version_exists(self):
|
||||
"""Test database version constant."""
|
||||
from langbot.pkg.utils import constants
|
||||
|
||||
assert hasattr(constants, 'required_database_version')
|
||||
assert isinstance(constants.required_database_version, int)
|
||||
|
||||
Reference in New Issue
Block a user