feat(agent-runner): finalize 4.x processor integration

This commit is contained in:
huanghuoguoguo
2026-07-12 15:44:05 +08:00
parent 29689962f3
commit e6384aae5d
109 changed files with 2200 additions and 1204 deletions
+16 -16
View File
@@ -69,7 +69,7 @@ class MockQuery:
self.pipeline_config = {
'ai': {
'runner': {
'id': 'plugin:langbot/local-agent/default',
'id': 'plugin:langbot-team/LocalAgent/default',
},
'runner_config': {},
},
@@ -133,7 +133,7 @@ class MockAgentRunOrchestrator:
return False
def resolve_runner_id_for_telemetry(self, query):
return 'plugin:langbot/local-agent/default'
return 'plugin:langbot-team/LocalAgent/default'
class MockApplication:
@@ -234,16 +234,16 @@ class TestConfigMigrationInChatHandler:
pipeline_config = {
'ai': {
'runner': {
'id': 'plugin:langbot/local-agent/default',
'id': 'plugin:langbot-team/LocalAgent/default',
},
},
}
runner_id = ConfigMigration.resolve_runner_id(pipeline_config)
assert runner_id == 'plugin:langbot/local-agent/default'
assert runner_id == 'plugin:langbot-team/LocalAgent/default'
def test_resolve_runner_id_from_old_format(self):
"""ConfigMigration resolves old runner aliases for compatibility."""
def test_old_runner_field_is_not_resolved(self):
"""The 4.x path requires ai.runner.id."""
pipeline_config = {
'ai': {
'runner': {
@@ -253,7 +253,7 @@ class TestConfigMigrationInChatHandler:
}
runner_id = ConfigMigration.resolve_runner_id(pipeline_config)
assert runner_id == 'plugin:langbot/local-agent/default'
assert runner_id is None
class TestErrorHandling:
@@ -268,18 +268,18 @@ class TestErrorHandling:
def test_runner_execution_error_retryable(self):
"""RunnerExecutionError should have retryable property."""
error = RunnerExecutionError(
'plugin:langbot/local-agent/default',
'plugin:langbot-team/LocalAgent/default',
'Upstream timeout',
retryable=True,
)
assert error.runner_id == 'plugin:langbot/local-agent/default'
assert error.runner_id == 'plugin:langbot-team/LocalAgent/default'
assert error.retryable is True
assert 'timeout' in str(error)
def test_runner_execution_error_not_retryable(self):
"""RunnerExecutionError can be non-retryable."""
error = RunnerExecutionError(
'plugin:langbot/local-agent/default',
'plugin:langbot-team/LocalAgent/default',
'Configuration error',
retryable=False,
)
@@ -288,11 +288,11 @@ class TestErrorHandling:
def test_runner_not_authorized_error_properties(self):
"""RunnerNotAuthorizedError should have bound_plugins property."""
error = RunnerNotAuthorizedError(
'plugin:langbot/local-agent/default',
['langbot/dify-agent'],
'plugin:langbot-team/LocalAgent/default',
['langbot-team/DifyAgent'],
)
assert error.runner_id == 'plugin:langbot/local-agent/default'
assert error.bound_plugins == ['langbot/dify-agent']
assert error.runner_id == 'plugin:langbot-team/LocalAgent/default'
assert error.bound_plugins == ['langbot-team/DifyAgent']
class TestChatHandlerImports:
@@ -500,7 +500,7 @@ class TestChatHandlerAsyncBehavior:
from langbot.pkg.pipeline import entities
orchestrator = MockAgentRunOrchestrator(
error=RunnerNotAuthorizedError('plugin:langbot/local-agent/default', ['other/plugin'])
error=RunnerNotAuthorizedError('plugin:langbot-team/LocalAgent/default', ['other/plugin'])
)
mock_ap = MockApplication(orchestrator=orchestrator)
mock_ap.plugin_connector.emit_event = AsyncMock(return_value=MockEventContext(prevented=False))
@@ -538,7 +538,7 @@ class TestChatHandlerAsyncBehavior:
from langbot.pkg.pipeline import entities
orchestrator = MockAgentRunOrchestrator(
error=RunnerExecutionError('plugin:langbot/local-agent/default', 'timeout', retryable=True)
error=RunnerExecutionError('plugin:langbot-team/LocalAgent/default', 'timeout', retryable=True)
)
mock_ap = MockApplication(orchestrator=orchestrator)
mock_ap.plugin_connector.emit_event = AsyncMock(return_value=MockEventContext(prevented=False))
+10 -154
View File
@@ -12,15 +12,15 @@ class TestResolveRunnerId:
pipeline_config = {
'ai': {
'runner': {
'id': 'plugin:langbot/local-agent/default',
'id': 'plugin:langbot-team/LocalAgent/default',
},
},
}
runner_id = ConfigMigration.resolve_runner_id(pipeline_config)
assert runner_id == 'plugin:langbot/local-agent/default'
assert runner_id == 'plugin:langbot-team/LocalAgent/default'
def test_resolves_old_runner_field(self):
def test_does_not_resolve_legacy_runner_field(self):
pipeline_config = {
'ai': {
'runner': {
@@ -30,33 +30,7 @@ class TestResolveRunnerId:
}
runner_id = ConfigMigration.resolve_runner_id(pipeline_config)
assert runner_id == 'plugin:langbot/local-agent/default'
def test_resolves_deerflow_and_weknora_legacy_runner_fields(self):
assert (
ConfigMigration.resolve_runner_id(
{
'ai': {
'runner': {
'runner': 'deerflow-api',
},
},
}
)
== 'plugin:langbot/deerflow-agent/default'
)
assert (
ConfigMigration.resolve_runner_id(
{
'ai': {
'runner': {
'runner': 'weknora-api',
},
},
}
)
== 'plugin:langbot/weknora-agent/default'
)
assert runner_id is None
def test_resolve_no_runner_config(self):
runner_id = ConfigMigration.resolve_runner_id({})
@@ -70,7 +44,7 @@ class TestResolveRunnerConfig:
pipeline_config = {
'ai': {
'runner_config': {
'plugin:langbot/local-agent/default': {
'plugin:langbot-team/LocalAgent/default': {
'model': 'uuid-123',
'custom_option': 10,
},
@@ -80,11 +54,11 @@ class TestResolveRunnerConfig:
config = ConfigMigration.resolve_runner_config(
pipeline_config,
'plugin:langbot/local-agent/default',
'plugin:langbot-team/LocalAgent/default',
)
assert config == {'model': 'uuid-123', 'custom_option': 10}
def test_reads_old_runner_block(self):
def test_does_not_read_legacy_runner_block(self):
pipeline_config = {
'ai': {
'local-agent': {
@@ -95,46 +69,14 @@ class TestResolveRunnerConfig:
config = ConfigMigration.resolve_runner_config(
pipeline_config,
'plugin:langbot/local-agent/default',
'plugin:langbot-team/LocalAgent/default',
)
assert config == {'model': {'primary': 'uuid-123', 'fallbacks': []}}
def test_reads_deerflow_and_weknora_legacy_runner_blocks(self):
pipeline_config = {
'ai': {
'deerflow-api': {
'api-base': 'http://127.0.0.1:2026',
'assistant-id': 'lead_agent',
},
'weknora-api': {
'base-url': 'http://localhost:8080/api/v1',
'app-type': 'agent',
},
},
}
deerflow_config = ConfigMigration.resolve_runner_config(
pipeline_config,
'plugin:langbot/deerflow-agent/default',
)
weknora_config = ConfigMigration.resolve_runner_config(
pipeline_config,
'plugin:langbot/weknora-agent/default',
)
assert deerflow_config == {
'api-base': 'http://127.0.0.1:2026',
'assistant-id': 'lead_agent',
}
assert weknora_config == {
'base-url': 'http://localhost:8080/api/v1',
'app-type': 'agent',
}
assert config == {}
def test_resolve_no_config(self):
config = ConfigMigration.resolve_runner_config(
{},
'plugin:langbot/local-agent/default',
'plugin:langbot-team/LocalAgent/default',
)
assert config == {}
@@ -169,89 +111,3 @@ class TestGetExpireTime:
def test_get_expire_time_default(self):
expire_time = ConfigMigration.get_expire_time({})
assert expire_time == 0
class TestNormalizePipelineConfig:
"""Tests for ConfigMigration.migrate_pipeline_config."""
def test_normalizes_current_containers(self):
config = {'ai': {}}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated == {'ai': {'runner': {}, 'runner_config': {}}}
def test_preserves_current_config(self):
config = {
'ai': {
'runner': {'id': 'plugin:test/my-runner/default'},
'runner_config': {
'plugin:test/my-runner/default': {'custom-option': 20},
},
},
}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated['ai']['runner']['id'] == 'plugin:test/my-runner/default'
assert migrated['ai']['runner_config']['plugin:test/my-runner/default']['custom-option'] == 20
def test_migrates_old_runner_blocks(self):
config = {
'ai': {
'runner': {'runner': 'local-agent'},
'local-agent': {'model': 'old-model', 'knowledge-base': 'kb_1'},
},
}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated['ai']['runner']['id'] == 'plugin:langbot/local-agent/default'
assert 'runner' not in migrated['ai']['runner']
assert 'local-agent' not in migrated['ai']
assert migrated['ai']['runner_config']['plugin:langbot/local-agent/default'] == {
'model': {'primary': 'old-model', 'fallbacks': []},
'knowledge-bases': ['kb_1'],
}
def test_migrates_deerflow_legacy_runner_block(self):
config = {
'ai': {
'runner': {'runner': 'deerflow-api'},
'deerflow-api': {
'api-base': 'http://127.0.0.1:2026',
'assistant-id': 'lead_agent',
},
},
}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated['ai']['runner']['id'] == 'plugin:langbot/deerflow-agent/default'
assert 'runner' not in migrated['ai']['runner']
assert 'deerflow-api' not in migrated['ai']
assert migrated['ai']['runner_config']['plugin:langbot/deerflow-agent/default'] == {
'api-base': 'http://127.0.0.1:2026',
'assistant-id': 'lead_agent',
}
def test_migrates_weknora_legacy_runner_block(self):
config = {
'ai': {
'runner': {'runner': 'weknora-api'},
'weknora-api': {
'base-url': 'http://localhost:8080/api/v1',
'app-type': 'agent',
},
},
}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated['ai']['runner']['id'] == 'plugin:langbot/weknora-agent/default'
assert 'runner' not in migrated['ai']['runner']
assert 'weknora-api' not in migrated['ai']
assert migrated['ai']['runner_config']['plugin:langbot/weknora-agent/default'] == {
'base-url': 'http://localhost:8080/api/v1',
'app-type': 'agent',
}
@@ -7,65 +7,6 @@ import json
from langbot.pkg.agent.runner.config_migration import ConfigMigration
class TestMigratePipelineConfig:
"""Tests for ConfigMigration.migrate_pipeline_config."""
def test_current_format_config_stays_unchanged(self):
config = {
'ai': {
'runner': {
'id': 'plugin:langbot/local-agent/default',
'expire-time': 0,
},
'runner_config': {
'plugin:langbot/local-agent/default': {
'model': {'primary': '', 'fallbacks': []},
'custom-option': 10,
},
},
},
}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated['ai']['runner']['id'] == 'plugin:langbot/local-agent/default'
assert migrated['ai']['runner_config']['plugin:langbot/local-agent/default']['custom-option'] == 10
def test_old_runner_field_is_mapped(self):
config = {
'ai': {
'runner': {
'runner': 'local-agent',
'expire-time': 3600,
},
'local-agent': {
'model': 'old-model',
},
},
}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated['ai']['runner'] == {
'expire-time': 3600,
'id': 'plugin:langbot/local-agent/default',
}
assert migrated['ai']['runner_config']['plugin:langbot/local-agent/default'] == {
'model': {'primary': 'old-model', 'fallbacks': []},
}
assert 'local-agent' not in migrated['ai']
def test_empty_config_is_unchanged(self):
config = {}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated == {}
def test_config_without_ai_section_is_unchanged(self):
config = {'trigger': {}}
migrated = ConfigMigration.migrate_pipeline_config(config)
assert migrated == {'trigger': {}}
class TestDefaultPipelineConfig:
"""Tests for default-pipeline-config.json format."""
@@ -97,14 +38,14 @@ class TestResolveRunnerId:
runner_id = ConfigMigration.resolve_runner_id(config)
assert runner_id == 'plugin:test/my-runner/default'
def test_old_runner_field_is_mapped(self):
def test_old_runner_field_is_not_supported(self):
config = {
'ai': {
'runner': {'runner': 'local-agent'},
},
}
runner_id = ConfigMigration.resolve_runner_id(config)
assert runner_id == 'plugin:langbot/local-agent/default'
assert runner_id is None
class TestResolveRunnerConfig:
@@ -114,18 +55,18 @@ class TestResolveRunnerConfig:
config = {
'ai': {
'runner_config': {
'plugin:langbot/local-agent/default': {'custom-option': 20},
'plugin:langbot-team/LocalAgent/default': {'custom-option': 20},
},
},
}
runner_config = ConfigMigration.resolve_runner_config(config, 'plugin:langbot/local-agent/default')
runner_config = ConfigMigration.resolve_runner_config(config, 'plugin:langbot-team/LocalAgent/default')
assert runner_config['custom-option'] == 20
def test_old_runner_block_is_read(self):
def test_old_runner_block_is_not_supported(self):
config = {
'ai': {
'local-agent': {'custom-option': 20},
},
}
runner_config = ConfigMigration.resolve_runner_config(config, 'plugin:langbot/local-agent/default')
assert runner_config == {'custom-option': 20}
runner_config = ConfigMigration.resolve_runner_config(config, 'plugin:langbot-team/LocalAgent/default')
assert runner_config == {}
@@ -158,27 +158,26 @@ class TestQueryConfigToAgentConfig:
assert agent_config.runner_id == "plugin:author/plugin/runner"
def test_config_to_agent_config_uses_legacy_runner_config_migration(self, mock_query):
"""Temporary query adapter must share the normal runner config resolver."""
def test_config_to_agent_config_uses_current_runner_config(self, mock_query):
"""Temporary query adapters use the current runner config container."""
mock_query.pipeline_config = {
"ai": {
"runner": {"runner": "local-agent"},
"local-agent": {
"model": "model-primary",
"knowledge-base": "kb-001",
"runner": {"id": "plugin:langbot-team/LocalAgent/default"},
"runner_config": {
"plugin:langbot-team/LocalAgent/default": {
"model": {"primary": "model-primary", "fallbacks": []},
"knowledge-bases": ["kb-001"],
},
},
}
}
agent_config = QueryEntryAdapter.config_to_agent_config(
mock_query,
"plugin:langbot/local-agent/default",
"plugin:langbot-team/LocalAgent/default",
)
assert agent_config.runner_config["model"] == {
"primary": "model-primary",
"fallbacks": [],
}
assert agent_config.runner_config["model"] == {"primary": "model-primary", "fallbacks": []}
assert agent_config.runner_config["knowledge-bases"] == ["kb-001"]
def test_resolver_projects_agent_scope(self, mock_query):
+6 -6
View File
@@ -544,10 +544,10 @@ class TestRETRIEVEKNOWLEDGEBASEBugFix:
pipeline_config = {
'ai': {
'runner': {
'id': 'plugin:langbot/local-agent/default',
'id': 'plugin:langbot-team/LocalAgent/default',
},
'runner_config': {
'plugin:langbot/local-agent/default': {
'plugin:langbot-team/LocalAgent/default': {
'knowledge-bases': ['kb_001'],
},
},
@@ -583,8 +583,8 @@ class TestRETRIEVEKNOWLEDGEBASEBugFix:
assert 'kb_custom' in allowed_kbs
def test_retrieve_kb_reads_old_runner_format(self):
"""Old runner format is resolved for migration compatibility."""
def test_retrieve_kb_does_not_read_old_runner_format(self):
"""The 4.x authorization path ignores legacy Pipeline runner fields."""
from langbot.pkg.agent.runner.config_migration import ConfigMigration
pipeline_config = {
@@ -600,8 +600,8 @@ class TestRETRIEVEKNOWLEDGEBASEBugFix:
runner_id = ConfigMigration.resolve_runner_id(pipeline_config)
runner_config = ConfigMigration.resolve_runner_config(pipeline_config, runner_id)
assert runner_id == 'plugin:langbot/local-agent/default'
assert runner_config.get('knowledge-bases') == ['kb_legacy']
assert runner_id is None
assert runner_config == {}
class TestHandlerActionAuthorization:
+15 -15
View File
@@ -16,12 +16,12 @@ class TestRunnerIdParsing:
def test_parse_plugin_runner_id(self):
"""Parse valid plugin runner ID."""
runner_id = 'plugin:langbot/local-agent/default'
runner_id = 'plugin:langbot-team/LocalAgent/default'
parts = parse_runner_id(runner_id)
assert parts.source == 'plugin'
assert parts.plugin_author == 'langbot'
assert parts.plugin_name == 'local-agent'
assert parts.plugin_author == 'langbot-team'
assert parts.plugin_name == 'LocalAgent'
assert parts.runner_name == 'default'
def test_parse_plugin_runner_id_complex_names(self):
@@ -36,7 +36,7 @@ class TestRunnerIdParsing:
def test_parse_invalid_plugin_runner_id_missing_parts(self):
"""Parse invalid plugin runner ID with missing parts."""
runner_id = 'plugin:langbot/local-agent'
runner_id = 'plugin:langbot-team/LocalAgent'
with pytest.raises(ValueError) as exc_info:
parse_runner_id(runner_id)
@@ -76,20 +76,20 @@ class TestRunnerIdFormatting:
"""Format plugin runner ID."""
runner_id = format_runner_id(
source='plugin',
plugin_author='langbot',
plugin_name='local-agent',
plugin_author='langbot-team',
plugin_name='LocalAgent',
runner_name='default',
)
assert runner_id == 'plugin:langbot/local-agent/default'
assert runner_id == 'plugin:langbot-team/LocalAgent/default'
def test_format_invalid_source(self):
"""Format runner ID with invalid source."""
with pytest.raises(ValueError) as exc_info:
format_runner_id(
source='builtin',
plugin_author='langbot',
plugin_name='local-agent',
plugin_author='langbot-team',
plugin_name='LocalAgent',
runner_name='default',
)
@@ -103,19 +103,19 @@ class TestRunnerIdParts:
"""Get plugin ID from parts."""
parts = RunnerIdParts(
source='plugin',
plugin_author='langbot',
plugin_name='local-agent',
plugin_author='langbot-team',
plugin_name='LocalAgent',
runner_name='default',
)
assert parts.to_plugin_id() == 'langbot/local-agent'
assert parts.to_plugin_id() == 'langbot-team/LocalAgent'
def test_frozen_dataclass(self):
"""RunnerIdParts should be immutable."""
parts = RunnerIdParts(
source='plugin',
plugin_author='langbot',
plugin_name='local-agent',
plugin_author='langbot-team',
plugin_name='LocalAgent',
runner_name='default',
)
@@ -128,7 +128,7 @@ class TestIsPluginRunnerId:
def test_is_plugin_runner_id_true(self):
"""Check plugin runner ID returns True."""
assert is_plugin_runner_id('plugin:langbot/local-agent/default') is True
assert is_plugin_runner_id('plugin:langbot-team/LocalAgent/default') is True
def test_is_plugin_runner_id_false(self):
"""Check non-plugin runner ID returns False."""
@@ -26,7 +26,7 @@ from langbot_plugin.api.entities.builtin.provider import session as provider_ses
from langbot_plugin.api.entities.builtin.resource import tool as resource_tool
RUNNER_ID = 'plugin:langbot/local-agent/default'
RUNNER_ID = 'plugin:langbot-team/LocalAgent/default'
class FakeLogger:
@@ -153,8 +153,8 @@ def make_descriptor() -> AgentRunnerDescriptor:
id=RUNNER_ID,
source='plugin',
label={'en_US': 'Local Agent'},
plugin_author='langbot',
plugin_name='local-agent',
plugin_author='langbot-team',
plugin_name='LocalAgent',
runner_name='default',
capabilities={
'streaming': True,
@@ -231,7 +231,7 @@ def make_query():
],
),
variables={
'_pipeline_bound_plugins': ['langbot/local-agent'],
'_pipeline_bound_plugins': ['langbot-team/LocalAgent'],
'_fallback_model_uuids': ['model_fallback'],
'_pipeline_bound_skills': ['demo'],
'public_param': 'visible',
@@ -354,8 +354,8 @@ async def test_orchestrator_runs_fake_plugin_with_authorized_context(clean_agent
assert messages[0].content == 'fake response'
assert plugin_connector.calls == [
{
'plugin_author': 'langbot',
'plugin_name': 'local-agent',
'plugin_author': 'langbot-team',
'plugin_name': 'LocalAgent',
'runner_name': 'default',
}
]
@@ -400,7 +400,7 @@ async def test_orchestrator_runs_fake_plugin_with_authorized_context(clean_agent
session_during_run = plugin_connector.sessions_during_run[0]
assert session_during_run is not None
assert session_during_run['plugin_identity'] == 'langbot/local-agent'
assert session_during_run['plugin_identity'] == 'langbot-team/LocalAgent'
assert session_during_run['authorization']['authorized_ids']['tool'] == {'langbot/test-tool/search'}
assert session_during_run['authorization']['authorized_ids']['skill'] == {'demo'}
assert await get_session_registry().get(context['run_id']) is None
+17 -17
View File
@@ -35,11 +35,11 @@ class FakeApplication:
# Return sample runner data
return [
{
'plugin_author': 'langbot',
'plugin_name': 'local-agent',
'plugin_author': 'langbot-team',
'plugin_name': 'LocalAgent',
'runner_name': 'default',
'manifest': {
'id': 'plugin:langbot/local-agent/default',
'id': 'plugin:langbot-team/LocalAgent/default',
'name': 'default',
'label': {'en_US': 'Local Agent'},
'capabilities': {'streaming': True},
@@ -98,11 +98,11 @@ class TestRegistryDiscovery:
runners = await registry.list_runners(use_cache=False)
# Should find 2 valid runners (langbot/local-agent and alice/my-agent)
# Should find 2 valid runners (langbot-team/LocalAgent and alice/my-agent)
assert len(runners) == 2
ids = [r.id for r in runners]
assert 'plugin:langbot/local-agent/default' in ids
assert 'plugin:langbot-team/LocalAgent/default' in ids
assert 'plugin:alice/my-agent/custom' in ids
@pytest.mark.asyncio
@@ -143,15 +143,15 @@ class TestRegistryDiscovery:
# First: get with bound_plugins filter (should not pollute cache)
descriptor = await registry.get(
'plugin:langbot/local-agent/default',
bound_plugins=['langbot/local-agent'],
'plugin:langbot-team/LocalAgent/default',
bound_plugins=['langbot-team/LocalAgent'],
)
assert descriptor.id == 'plugin:langbot/local-agent/default'
assert descriptor.id == 'plugin:langbot-team/LocalAgent/default'
# Cache should contain ALL runners (both langbot and alice)
assert registry._cache is not None
assert len(registry._cache) == 2 # Both runners in cache
assert 'plugin:langbot/local-agent/default' in registry._cache
assert 'plugin:langbot-team/LocalAgent/default' in registry._cache
assert 'plugin:alice/my-agent/custom' in registry._cache
# Second: list_runners without filter should return ALL runners
@@ -173,11 +173,11 @@ class TestRegistryGet:
ap = FakeApplication()
registry = AgentRunnerRegistry(ap)
descriptor = await registry.get('plugin:langbot/local-agent/default')
descriptor = await registry.get('plugin:langbot-team/LocalAgent/default')
assert descriptor.id == 'plugin:langbot/local-agent/default'
assert descriptor.plugin_author == 'langbot'
assert descriptor.plugin_name == 'local-agent'
assert descriptor.id == 'plugin:langbot-team/LocalAgent/default'
assert descriptor.plugin_author == 'langbot-team'
assert descriptor.plugin_name == 'LocalAgent'
assert descriptor.runner_name == 'default'
@pytest.mark.asyncio
@@ -199,8 +199,8 @@ class TestRegistryGet:
# Authorized - langbot plugin in bound list
descriptor = await registry.get(
'plugin:langbot/local-agent/default',
bound_plugins=['langbot/local-agent'],
'plugin:langbot-team/LocalAgent/default',
bound_plugins=['langbot-team/LocalAgent'],
)
assert descriptor is not None
@@ -208,7 +208,7 @@ class TestRegistryGet:
with pytest.raises(RunnerNotAuthorizedError):
await registry.get(
'plugin:alice/my-agent/custom',
bound_plugins=['langbot/local-agent'],
bound_plugins=['langbot-team/LocalAgent'],
)
@@ -226,7 +226,7 @@ class TestRegistryMetadataForPipeline:
# Should have options for each runner
assert len(options) == 2
option_ids = [o['name'] for o in options]
assert 'plugin:langbot/local-agent/default' in option_ids
assert 'plugin:langbot-team/LocalAgent/default' in option_ids
assert 'plugin:alice/my-agent/custom' in option_ids
# Config comes from the typed manifest.
@@ -32,11 +32,11 @@ class FakeApplication:
def make_descriptor():
"""Create a test descriptor."""
return AgentRunnerDescriptor(
id='plugin:langbot/local-agent/default',
id='plugin:langbot-team/LocalAgent/default',
source='plugin',
label={'en_US': 'Local Agent', 'zh_Hans': '内置 Agent'},
plugin_author='langbot',
plugin_name='local-agent',
plugin_author='langbot-team',
plugin_name='LocalAgent',
runner_name='default',
capabilities={'streaming': True},
)
@@ -190,7 +190,7 @@ class TestNormalizeRunFailed:
with pytest.raises(RunnerExecutionError) as exc_info:
await normalizer.normalize(result_dict, descriptor)
assert exc_info.value.runner_id == 'plugin:langbot/local-agent/default'
assert exc_info.value.runner_id == 'plugin:langbot-team/LocalAgent/default'
assert exc_info.value.retryable is True
assert 'timeout' in str(exc_info.value)