mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-26 20:27:13 +00:00
fix(web): make processor debugging reliable
This commit is contained in:
@@ -901,7 +901,7 @@ async def test_orchestrator_enforces_total_runner_deadline(clean_agent_state):
|
||||
[message async for message in orchestrator.run_from_query(query)]
|
||||
|
||||
assert exc_info.value.retryable is True
|
||||
assert 'runner.timeout' in str(exc_info.value)
|
||||
assert exc_info.value.error_code == 'runner.timeout'
|
||||
assert await get_session_registry().list_active_runs() == []
|
||||
|
||||
|
||||
@@ -1012,6 +1012,7 @@ class TestQueryEntrySessionQueryId:
|
||||
]
|
||||
)
|
||||
ap = FakeApplication(plugin_connector, db_engine)
|
||||
|
||||
async def build_resource_context(execution_query):
|
||||
from langbot.pkg.provider.tools.loaders.mcp import (
|
||||
_execution_context_from_query,
|
||||
@@ -1025,9 +1026,7 @@ class TestQueryEntrySessionQueryId:
|
||||
return 'Pinned documentation'
|
||||
|
||||
mcp_loader = types.SimpleNamespace(
|
||||
build_resource_context_for_query=AsyncMock(
|
||||
side_effect=build_resource_context
|
||||
)
|
||||
build_resource_context_for_query=AsyncMock(side_effect=build_resource_context)
|
||||
)
|
||||
ap.tool_mgr = types.SimpleNamespace(mcp_tool_loader=mcp_loader)
|
||||
orchestrator = AgentRunOrchestrator(ap, FakeRegistry(descriptor))
|
||||
@@ -1105,14 +1104,8 @@ class TestQueryEntrySessionQueryId:
|
||||
assert 'Pinned documentation' in plugin_connector.contexts[0]['input']['contents'][0]['text']
|
||||
assert event.input.text == 'hello'
|
||||
assert event.input.contents[0].text == 'hello'
|
||||
assert (
|
||||
plugin_connector.contexts[0]['conversation']['workspace_id']
|
||||
== TEST_CONTEXT.workspace_uuid
|
||||
)
|
||||
assert (
|
||||
plugin_connector.contexts[0]['runtime']['metadata']['workspace_id']
|
||||
== TEST_CONTEXT.workspace_uuid
|
||||
)
|
||||
assert plugin_connector.contexts[0]['conversation']['workspace_id'] == TEST_CONTEXT.workspace_uuid
|
||||
assert plugin_connector.contexts[0]['runtime']['metadata']['workspace_id'] == TEST_CONTEXT.workspace_uuid
|
||||
assert 'Pinned documentation' not in str(execution_query.user_message.content)
|
||||
mcp_loader.build_resource_context_for_query.assert_awaited_once_with(execution_query)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Tests for agent runner result normalizer."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
@@ -12,6 +13,7 @@ from langbot_plugin.api.entities.builtin.provider import message as provider_mes
|
||||
|
||||
class FakeApplication:
|
||||
"""Fake Application for testing."""
|
||||
|
||||
def __init__(self):
|
||||
class FakeLogger:
|
||||
def __init__(self):
|
||||
@@ -19,10 +21,13 @@ class FakeApplication:
|
||||
|
||||
def info(self, msg):
|
||||
pass
|
||||
|
||||
def debug(self, msg):
|
||||
pass
|
||||
|
||||
def warning(self, msg):
|
||||
self.warnings.append(msg)
|
||||
|
||||
def error(self, msg):
|
||||
pass
|
||||
|
||||
@@ -192,6 +197,7 @@ class TestNormalizeRunFailed:
|
||||
|
||||
assert exc_info.value.runner_id == 'plugin:langbot-team/LocalAgent/default'
|
||||
assert exc_info.value.retryable is True
|
||||
assert exc_info.value.error_code == 'upstream.timeout'
|
||||
assert 'timeout' in str(exc_info.value)
|
||||
|
||||
|
||||
@@ -290,6 +296,7 @@ class TestNormalizeNonMessageResults:
|
||||
assert result is None
|
||||
assert app.logger.warnings
|
||||
|
||||
|
||||
class TestNormalizeInvalidResults:
|
||||
"""Tests for handling invalid results."""
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ from unittest.mock import ANY, AsyncMock
|
||||
import pytest
|
||||
import quart
|
||||
|
||||
from langbot.pkg.agent.runner.errors import RunnerExecutionError
|
||||
|
||||
core_app_module = types.ModuleType('langbot.pkg.core.app')
|
||||
core_app_module.Application = object
|
||||
sys.modules.setdefault('langbot.pkg.core.app', core_app_module)
|
||||
@@ -142,3 +144,28 @@ async def test_debug_agent_returns_bad_request_for_invalid_event():
|
||||
'code': -1,
|
||||
'msg': 'Invalid event_type',
|
||||
}
|
||||
|
||||
|
||||
async def test_debug_agent_returns_actionable_runner_error():
|
||||
agent_service = SimpleNamespace(
|
||||
debug_agent=AsyncMock(
|
||||
side_effect=RunnerExecutionError(
|
||||
'plugin:langbot-team/DifyAgent/default',
|
||||
'api-key is required',
|
||||
error_code='dify.config_invalid',
|
||||
)
|
||||
),
|
||||
)
|
||||
client = await _create_test_client(agent_service)
|
||||
|
||||
response = await client.post(
|
||||
'/api/v1/agents/agent-1/debug',
|
||||
json={'event_type': 'message.received', 'text': 'hello'},
|
||||
headers={'Authorization': 'Bearer test-token'},
|
||||
)
|
||||
|
||||
assert response.status_code == 422
|
||||
assert await response.get_json() == {
|
||||
'code': 'dify.config_invalid',
|
||||
'msg': 'api-key is required',
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -53,6 +55,23 @@ async def test_matches_any_rejects_pattern_and_input_amplification():
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bundled_sensitive_words_fit_within_pattern_limit():
|
||||
config_path = Path(__file__).parents[3] / 'src/langbot/templates/metadata/sensitive-words.json'
|
||||
config = json.loads(config_path.read_text())
|
||||
|
||||
assert len(config['words']) <= safe_regex.MAX_PATTERN_COUNT
|
||||
found, masked = await safe_regex.mask_patterns(
|
||||
config['words'],
|
||||
'普通消息',
|
||||
mask=config['mask'],
|
||||
mask_word=config['mask_word'],
|
||||
)
|
||||
|
||||
assert found is False
|
||||
assert masked == '普通消息'
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mask_patterns_bounds_replacement_growth_and_masks_matches():
|
||||
found, masked = await safe_regex.mask_patterns(
|
||||
|
||||
Reference in New Issue
Block a user