mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-09 20:50:58 +00:00
chore(merge): sync master into dev/4.11.x
This commit is contained in:
@@ -15,6 +15,9 @@ import pytest
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
from importlib import import_module
|
||||
|
||||
from langbot_plugin.api.entities.builtin.provider import session as provider_session
|
||||
|
||||
from langbot.pkg.agent.runner.descriptor import AgentRunnerDescriptor
|
||||
from tests.factories import (
|
||||
FakeApp,
|
||||
text_query,
|
||||
@@ -24,6 +27,28 @@ from tests.factories import (
|
||||
)
|
||||
|
||||
|
||||
RUNNER_ID = 'plugin:langbot-team/LocalAgent/default'
|
||||
|
||||
|
||||
def attach_agent_runner_descriptor(app):
|
||||
descriptor = AgentRunnerDescriptor(
|
||||
id=RUNNER_ID,
|
||||
source='plugin',
|
||||
label={'en_US': 'Local Agent'},
|
||||
plugin_author='langbot-team',
|
||||
plugin_name='LocalAgent',
|
||||
runner_name='default',
|
||||
config_schema=[
|
||||
{'name': 'model', 'type': 'model-fallback-selector'},
|
||||
{'name': 'prompt', 'type': 'prompt-editor', 'default': []},
|
||||
],
|
||||
capabilities={'tool_calling': True, 'multimodal_input': True},
|
||||
)
|
||||
app.agent_runner_registry = Mock()
|
||||
app.agent_runner_registry.get = AsyncMock(return_value=descriptor)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
|
||||
|
||||
def get_preproc_module():
|
||||
"""Lazy import to avoid circular import issues."""
|
||||
return import_module('langbot.pkg.pipeline.preproc.preproc')
|
||||
@@ -34,48 +59,18 @@ def get_entities_module():
|
||||
return import_module('langbot.pkg.pipeline.entities')
|
||||
|
||||
|
||||
RUNNER_ID = 'plugin:langbot-team/LocalAgent/default'
|
||||
def make_session(
|
||||
launcher_type: provider_session.LauncherTypes = provider_session.LauncherTypes.PERSON,
|
||||
launcher_id: int = 12345,
|
||||
) -> provider_session.Session:
|
||||
"""Build a scope-aware Session that matches the shared Query factory."""
|
||||
|
||||
|
||||
def attach_agent_runner_descriptor(app, *, multimodal_input=True, tool_calling=True):
|
||||
"""Attach a schema-backed AgentRunner descriptor to a FakeApp."""
|
||||
from langbot.pkg.agent.runner.descriptor import AgentRunnerDescriptor
|
||||
|
||||
descriptor = AgentRunnerDescriptor(
|
||||
id=RUNNER_ID,
|
||||
source='plugin',
|
||||
label={'en_US': 'Local Agent'},
|
||||
plugin_author='langbot-team',
|
||||
plugin_name='LocalAgent',
|
||||
runner_name='default',
|
||||
config_schema=[
|
||||
{'name': 'model', 'type': 'model-fallback-selector'},
|
||||
{'name': 'prompt', 'type': 'prompt-editor', 'default': []},
|
||||
],
|
||||
capabilities={
|
||||
'tool_calling': tool_calling,
|
||||
'multimodal_input': multimodal_input,
|
||||
},
|
||||
return provider_session.Session(
|
||||
launcher_type=launcher_type,
|
||||
launcher_id=launcher_id,
|
||||
sender_id=12345,
|
||||
bot_uuid='test-bot-uuid',
|
||||
)
|
||||
app.agent_runner_registry = Mock()
|
||||
app.agent_runner_registry.get = AsyncMock(return_value=descriptor)
|
||||
return descriptor
|
||||
|
||||
|
||||
def agent_runner_pipeline_config(model_config, *, prompt='default'):
|
||||
return {
|
||||
'ai': {
|
||||
'runner': {'id': RUNNER_ID},
|
||||
'runner_config': {
|
||||
RUNNER_ID: {
|
||||
'model': model_config,
|
||||
'prompt': prompt,
|
||||
},
|
||||
},
|
||||
},
|
||||
'output': {'misc': {'at-sender': False}},
|
||||
'trigger': {'misc': {}},
|
||||
}
|
||||
|
||||
|
||||
class TestPreProcessorNormalText:
|
||||
@@ -89,9 +84,7 @@ class TestPreProcessorNormalText:
|
||||
|
||||
app = FakeApp()
|
||||
# Mock session manager to return a session
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
# Mock conversation
|
||||
@@ -112,7 +105,7 @@ class TestPreProcessorNormalText:
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
|
||||
# Mock tool manager
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
# Mock plugin connector
|
||||
mock_event_ctx = Mock()
|
||||
@@ -135,9 +128,7 @@ class TestPreProcessorNormalText:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -150,7 +141,7 @@ class TestPreProcessorNormalText:
|
||||
mock_model = Mock()
|
||||
mock_model.model_entity = Mock(uuid='test-model', abilities=['func_call'])
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
@@ -175,9 +166,7 @@ class TestPreProcessorEmptyMessage:
|
||||
entities = get_entities_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -188,7 +177,7 @@ class TestPreProcessorEmptyMessage:
|
||||
app.sess_mgr.get_conversation = AsyncMock(return_value=mock_conversation)
|
||||
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=None)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
@@ -214,9 +203,7 @@ class TestPreProcessorImageSegment:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -230,7 +217,7 @@ class TestPreProcessorImageSegment:
|
||||
mock_model = Mock()
|
||||
mock_model.model_entity = Mock(uuid='vision-model', abilities=['func_call', 'vision'])
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
@@ -262,9 +249,7 @@ class TestPreProcessorImageSegment:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -278,7 +263,7 @@ class TestPreProcessorImageSegment:
|
||||
mock_model = Mock()
|
||||
mock_model.model_entity = Mock(uuid='text-only-model', abilities=['func_call'])
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
@@ -301,9 +286,7 @@ class TestPreProcessorModelSelection:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -316,7 +299,6 @@ class TestPreProcessorModelSelection:
|
||||
mock_model = Mock()
|
||||
mock_model.model_entity = Mock(uuid='primary-model-uuid', abilities=['func_call'])
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
attach_agent_runner_descriptor(app)
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
@@ -327,9 +309,19 @@ class TestPreProcessorModelSelection:
|
||||
query = text_query('hello')
|
||||
|
||||
# Set pipeline config with primary model
|
||||
query.pipeline_config = agent_runner_pipeline_config(
|
||||
{'primary': 'primary-model-uuid', 'fallbacks': []},
|
||||
)
|
||||
query.pipeline_config = {
|
||||
'ai': {
|
||||
'runner': {'id': RUNNER_ID},
|
||||
'runner_config': {
|
||||
RUNNER_ID: {
|
||||
'model': {'primary': 'primary-model-uuid', 'fallbacks': []},
|
||||
'prompt': [],
|
||||
},
|
||||
},
|
||||
},
|
||||
'output': {'misc': {'at-sender': False}},
|
||||
'trigger': {'misc': {}},
|
||||
}
|
||||
|
||||
result = await stage.process(query, 'PreProcessor')
|
||||
|
||||
@@ -341,9 +333,7 @@ class TestPreProcessorModelSelection:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -360,7 +350,7 @@ class TestPreProcessorModelSelection:
|
||||
mock_fallback = Mock()
|
||||
mock_fallback.model_entity = Mock(uuid='fallback-uuid', abilities=['func_call'])
|
||||
|
||||
async def mock_get_model(uuid):
|
||||
async def mock_get_model(_context, uuid):
|
||||
if uuid == 'primary-uuid':
|
||||
return mock_primary
|
||||
elif uuid == 'fallback-uuid':
|
||||
@@ -368,7 +358,6 @@ class TestPreProcessorModelSelection:
|
||||
raise ValueError(f'Model {uuid} not found')
|
||||
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(side_effect=mock_get_model)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
attach_agent_runner_descriptor(app)
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
@@ -378,9 +367,19 @@ class TestPreProcessorModelSelection:
|
||||
stage = preproc.PreProcessor(app)
|
||||
query = text_query('hello')
|
||||
|
||||
query.pipeline_config = agent_runner_pipeline_config(
|
||||
{'primary': 'primary-uuid', 'fallbacks': ['fallback-uuid']},
|
||||
)
|
||||
query.pipeline_config = {
|
||||
'ai': {
|
||||
'runner': {'id': RUNNER_ID},
|
||||
'runner_config': {
|
||||
RUNNER_ID: {
|
||||
'model': {'primary': 'primary-uuid', 'fallbacks': ['fallback-uuid']},
|
||||
'prompt': [],
|
||||
},
|
||||
},
|
||||
},
|
||||
'output': {'misc': {'at-sender': False}},
|
||||
'trigger': {'misc': {}},
|
||||
}
|
||||
|
||||
result = await stage.process(query, 'PreProcessor')
|
||||
|
||||
@@ -397,9 +396,7 @@ class TestPreProcessorVariables:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -410,7 +407,7 @@ class TestPreProcessorVariables:
|
||||
app.sess_mgr.get_conversation = AsyncMock(return_value=mock_conversation)
|
||||
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=None)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
@@ -434,9 +431,10 @@ class TestPreProcessorVariables:
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='group')
|
||||
mock_session.launcher_id = 99999
|
||||
mock_session = make_session(
|
||||
provider_session.LauncherTypes.GROUP,
|
||||
99999,
|
||||
)
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -447,7 +445,7 @@ class TestPreProcessorVariables:
|
||||
app.sess_mgr.get_conversation = AsyncMock(return_value=mock_conversation)
|
||||
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=None)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.tool_mgr.get_all_tools = AsyncMock(return_value=[])
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
@@ -462,69 +460,17 @@ class TestPreProcessorVariables:
|
||||
assert 'group_name' in variables
|
||||
assert 'sender_name' in variables
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize('invalid_value', [0, None, 'false'])
|
||||
@pytest.mark.parametrize(
|
||||
('configured_skills', 'expected_skills'),
|
||||
[
|
||||
(['bound-skill'], ['bound-skill']),
|
||||
(None, []),
|
||||
('bound-skill', []),
|
||||
],
|
||||
)
|
||||
async def test_malformed_enable_all_skills_flag_uses_bound_skills(
|
||||
self,
|
||||
invalid_value,
|
||||
configured_skills,
|
||||
expected_skills,
|
||||
):
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
mock_conversation.prompt = Mock(messages=[])
|
||||
mock_conversation.prompt.copy = Mock(return_value=Mock(messages=[]))
|
||||
mock_conversation.messages = []
|
||||
mock_conversation.uuid = None
|
||||
app.sess_mgr.get_conversation = AsyncMock(return_value=mock_conversation)
|
||||
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=None)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(return_value=[])
|
||||
app.pipeline_service.get_pipeline = AsyncMock(
|
||||
return_value={
|
||||
'extensions_preferences': {
|
||||
'enable_all_skills': invalid_value,
|
||||
'skills': configured_skills,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
app.plugin_connector.emit_event = AsyncMock(return_value=mock_event_ctx)
|
||||
|
||||
result = await preproc.PreProcessor(app).process(text_query('hello'), 'PreProcessor')
|
||||
|
||||
assert result.new_query.variables['_pipeline_bound_skills'] == expected_skills
|
||||
|
||||
|
||||
class TestPreProcessorToolSelection:
|
||||
"""Tests for generic AgentRunner tool selection."""
|
||||
"""Tests for Local Agent tool selection."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_agent_runner_filters_selected_tools(self):
|
||||
async def test_local_agent_filters_selected_tools(self):
|
||||
"""Only selected tools should be exposed when all-tools mode is off."""
|
||||
preproc = get_preproc_module()
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
mock_session = make_session()
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
@@ -537,98 +483,37 @@ class TestPreProcessorToolSelection:
|
||||
mock_model = Mock()
|
||||
mock_model.model_entity = Mock(uuid='primary-model-uuid', abilities=['func_call'])
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
attach_agent_runner_descriptor(app)
|
||||
app.tool_mgr.get_resolved_tool_catalog = AsyncMock(
|
||||
return_value=[
|
||||
{
|
||||
'name': 'exec',
|
||||
'source': 'builtin',
|
||||
'description': 'Execute',
|
||||
'parameters': {},
|
||||
},
|
||||
{
|
||||
'name': 'plugin_tool',
|
||||
'source': 'plugin',
|
||||
'source_id': 'test/plugin',
|
||||
'description': 'Plugin tool',
|
||||
'parameters': {},
|
||||
},
|
||||
{
|
||||
'name': 'mcp_tool',
|
||||
'source': 'mcp',
|
||||
'source_id': 'mcp-server',
|
||||
'description': 'MCP tool',
|
||||
'parameters': {},
|
||||
},
|
||||
{'name': 'exec', 'source': 'builtin'},
|
||||
{'name': 'plugin_tool', 'source': 'plugin', 'source_id': 'test/plugin'},
|
||||
{'name': 'mcp_tool', 'source': 'mcp', 'source_id': 'test-mcp'},
|
||||
]
|
||||
)
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
app.plugin_connector.emit_event = AsyncMock(return_value=mock_event_ctx)
|
||||
attach_agent_runner_descriptor(app)
|
||||
|
||||
stage = preproc.PreProcessor(app)
|
||||
query = text_query('hello')
|
||||
query.pipeline_config = agent_runner_pipeline_config(
|
||||
{'primary': 'primary-model-uuid', 'fallbacks': []},
|
||||
)
|
||||
query.pipeline_config['ai']['runner_config'][RUNNER_ID].update(
|
||||
{
|
||||
'enable-all-tools': False,
|
||||
'tools': ['plugin_tool'],
|
||||
}
|
||||
)
|
||||
query.pipeline_config = {
|
||||
'ai': {
|
||||
'runner': {'id': RUNNER_ID},
|
||||
'runner_config': {
|
||||
RUNNER_ID: {
|
||||
'model': {'primary': 'primary-model-uuid', 'fallbacks': []},
|
||||
'prompt': [],
|
||||
'enable-all-tools': False,
|
||||
'tools': ['plugin_tool'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'output': {'misc': {'at-sender': False}},
|
||||
'trigger': {'misc': {}},
|
||||
}
|
||||
|
||||
result = await stage.process(query, 'PreProcessor')
|
||||
|
||||
assert [tool.name for tool in result.new_query.use_funcs] == ['plugin_tool']
|
||||
assert result.new_query.variables['_host_tool_source_refs'] == {
|
||||
'plugin_tool': {'source': 'plugin', 'source_id': 'test/plugin'},
|
||||
}
|
||||
|
||||
|
||||
class TestPreProcessorMCPResourceContext:
|
||||
"""Tests for deferring MCP context until the run-scoped execution input."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pinned_context_does_not_mutate_preprocessed_input(self):
|
||||
preproc = get_preproc_module()
|
||||
from langbot.pkg.agent.runner.query_entry_adapter import QueryEntryAdapter
|
||||
|
||||
app = FakeApp()
|
||||
mock_session = Mock()
|
||||
mock_session.launcher_type = Mock(value='person')
|
||||
mock_session.launcher_id = 12345
|
||||
app.sess_mgr.get_session = AsyncMock(return_value=mock_session)
|
||||
|
||||
mock_conversation = Mock()
|
||||
mock_conversation.prompt = Mock(messages=[])
|
||||
mock_conversation.prompt.copy = Mock(return_value=Mock(messages=[]))
|
||||
mock_conversation.messages = []
|
||||
mock_conversation.uuid = 'conversation-1'
|
||||
app.sess_mgr.get_conversation = AsyncMock(return_value=mock_conversation)
|
||||
|
||||
mock_model = Mock()
|
||||
mock_model.model_entity = Mock(uuid='primary-model-uuid', abilities=[])
|
||||
app.model_mgr.get_model_by_uuid = AsyncMock(return_value=mock_model)
|
||||
mcp_loader = Mock()
|
||||
mcp_loader.build_resource_context_for_query = AsyncMock(return_value='Pinned documentation')
|
||||
app.tool_mgr.mcp_tool_loader = mcp_loader
|
||||
|
||||
mock_event_ctx = Mock()
|
||||
mock_event_ctx.event = Mock(default_prompt=[], prompt=[])
|
||||
app.plugin_connector.emit_event = AsyncMock(return_value=mock_event_ctx)
|
||||
attach_agent_runner_descriptor(app, tool_calling=False)
|
||||
|
||||
query = text_query('hello')
|
||||
query.launcher_id = '12345'
|
||||
query.pipeline_config = agent_runner_pipeline_config(
|
||||
{'primary': 'primary-model-uuid', 'fallbacks': []},
|
||||
)
|
||||
|
||||
result = await preproc.PreProcessor(app).process(query, 'PreProcessor')
|
||||
event = QueryEntryAdapter.query_to_event(result.new_query)
|
||||
|
||||
assert event.input.text == 'hello'
|
||||
assert 'Pinned documentation' not in str(event.input.contents)
|
||||
mcp_loader.build_resource_context_for_query.assert_not_awaited()
|
||||
|
||||
Reference in New Issue
Block a user