feat(agent-runner): integrate AgentRunner Protocol v1 with plugin system

Phase 0 integration complete - verified minimal loop with local-agent stub runner.

Changes:
- Add AgentRunOrchestrator for plugin-based agent execution
- Add AgentResultNormalizer for Protocol v1 result conversion
- Add AgentRunnerDescriptor for runner ID parsing (plugin:author/name/runner)
- Update chat handler to use new orchestrator instead of direct runner lookup
- Add plugin handler methods for list_agent_runners and run_agent
- Add connector methods for AgentRunner protocol forwarding
- Update pipeline API to include runner options in metadata
- Add integration docs and implementation plan

Integration verified:
- Runner: plugin:langbot/local-agent/default
- Input: "你好"
- Output: [stub] Echo: 你好
- Date: 2026-05-10 10:09

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
huanghuoguoguo
2026-05-10 10:11:54 +08:00
parent b7dcda8b23
commit 5aaa422250
29 changed files with 3955 additions and 298 deletions

View File

@@ -31,7 +31,7 @@ class PipelineService:
self.ap = ap
async def get_pipeline_metadata(self) -> list[dict]:
"""Get pipeline metadata with dynamically loaded plugin runners"""
"""Get pipeline metadata with dynamically loaded plugin runners from registry"""
import copy
# Deep copy AI metadata to avoid modifying the original
@@ -48,43 +48,20 @@ class PipelineService:
# Find the runner select config
for config_item in runner_stage.get('config', []):
if config_item.get('name') == 'runner':
# Get plugin agent runners
# Get plugin agent runners from registry
try:
plugin_runners = await self.ap.plugin_connector.list_agent_runners()
runner_options, runner_stages = await self.ap.agent_runner_registry.get_runner_metadata_for_pipeline()
# Add plugin runners to options
for runner in plugin_runners:
manifest = runner.get('manifest', {})
metadata = manifest.get('metadata', {})
for option in runner_options:
config_item['options'].append(option)
# Format: plugin:author/plugin_name/runner_name
runner_value = (
f'plugin:{runner["plugin_author"]}/{runner["plugin_name"]}/{runner["runner_name"]}'
)
# Add to options
config_item['options'].append(
{
'name': runner_value,
'label': metadata.get('label', {runner['runner_name']: runner['runner_name']}),
'description': metadata.get('description'),
}
)
# Add corresponding stage configuration for this runner
spec_config = manifest.get('spec', {}).get('config', [])
if spec_config:
ai_metadata['stages'].append(
{
'name': runner_value,
'label': metadata.get('label', {runner['runner_name']: runner['runner_name']}),
'description': metadata.get('description'),
'config': spec_config,
}
)
# Add corresponding stage configuration for each runner
for stage_config in runner_stages:
ai_metadata['stages'].append(stage_config)
except Exception as e:
self.ap.logger.warning(f'Failed to load plugin agent runners: {e}')
self.ap.logger.warning(f'Failed to load plugin agent runners from registry: {e}')
return [
self.ap.pipeline_config_meta_trigger,