feat(runner): unify plugin execution across agents and event processors

This commit is contained in:
RockChinQ
2026-09-10 18:04:38 +08:00
parent 8903a40c41
commit f24a7c9bb2
223 changed files with 4091 additions and 3068 deletions
@@ -1,7 +1,7 @@
[
{
"id": "qa-agent-runner-behaviors",
"title": "Deterministic AgentRunner behavior matrix",
"title": "Deterministic Runner behavior matrix",
"kind": "json",
"path": "fixtures/agent-runner/qa-runner-behaviors.json",
"related_cases": [
@@ -13,7 +13,7 @@
},
{
"id": "qa-agent-runner-source",
"title": "QA deterministic AgentRunner fixture source",
"title": "QA deterministic Runner fixture source",
"kind": "plugin_source",
"path": "fixtures/plugins/qa-agent-runner/manifest.yaml",
"related_cases": [
@@ -22,11 +22,11 @@
"agent-runner-live-install",
"agent-runner-qa-debug-chat"
],
"checks": ["exists", "qa_agent_runner_source"]
"checks": ["exists", "qa_runner_source"]
},
{
"id": "qa-agent-runner-package",
"title": "QA deterministic AgentRunner prebuilt package",
"title": "QA deterministic Runner prebuilt package",
"kind": "plugin_package",
"path": "fixtures/plugins/qa-agent-runner/dist/qa-agent-runner-0.1.0.lbpkg",
"related_cases": [
@@ -1,6 +1,6 @@
# QA AgentRunner Fixture
# QA Runner Fixture
Deterministic AgentRunner plugin source used by `langbot-skills` probes and future browser release-gate cases.
Deterministic Runner plugin source used by `langbot-skills` probes and future browser release-gate cases.
Runner id after installation should be:
@@ -10,6 +10,6 @@ plugin:qa/agent-runner/default
Expected behavior:
- normal input returns `QA_AGENT_RUNNER_OK:<input>`
- normal input returns `QA_RUNNER_OK:<input>`
- input containing `stream` emits streaming chunks then completes
- input containing `fail` returns `QA_AGENT_RUNNER_CONTROLLED_FAILURE`
- input containing `fail` returns `QA_RUNNER_CONTROLLED_FAILURE`
@@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="QA AgentRunner icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="QA Runner icon">
<rect width="64" height="64" rx="12" fill="#111827"/>
<path d="M16 20h32v22H35l-7 8v-8H16z" fill="#22c55e"/>
<path d="M24 30h16" stroke="#111827" stroke-width="4" stroke-linecap="round"/>

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 301 B

@@ -1,39 +0,0 @@
from __future__ import annotations
import typing
from langbot_plugin.api.definition.components.agent_runner.runner import AgentRunner
from langbot_plugin.api.entities.builtin.agent_runner import AgentRunContext, AgentRunResult
from langbot_plugin.api.entities.builtin.provider.message import Message, MessageChunk
class DefaultAgentRunner(AgentRunner):
async def run(
self,
ctx: AgentRunContext,
) -> typing.AsyncGenerator[AgentRunResult, None]:
text = (ctx.input.to_text() or "").strip()
if "fail" in text.lower():
yield AgentRunResult.run_failed(
ctx.run_id,
error="QA_AGENT_RUNNER_CONTROLLED_FAILURE",
code="qa.controlled_failure",
retryable=False,
)
return
content = f"QA_AGENT_RUNNER_OK:{text or 'empty'}"
if "stream" in text.lower():
for chunk in ("QA_", "AGENT_", f"RUNNER_OK:{text}"):
yield AgentRunResult.message_delta(
ctx.run_id,
MessageChunk(role="assistant", content=chunk),
)
yield AgentRunResult.run_completed(ctx.run_id, finish_reason="stop")
return
yield AgentRunResult.run_completed(
ctx.run_id,
Message(role="assistant", content=content),
finish_reason="stop",
)
@@ -0,0 +1,39 @@
from __future__ import annotations
import typing
from langbot_plugin.api.definition.components.runner.runner import Runner
from langbot_plugin.api.entities.builtin.runner import RunnerContext, RunnerResult
from langbot_plugin.api.entities.builtin.provider.message import Message, MessageChunk
class DefaultRunner(Runner):
async def run(
self,
ctx: RunnerContext,
) -> typing.AsyncGenerator[RunnerResult, None]:
text = (ctx.input.to_text() or '').strip()
if 'fail' in text.lower():
yield RunnerResult.run_failed(
ctx.run_id,
error='QA_RUNNER_CONTROLLED_FAILURE',
code='qa.controlled_failure',
retryable=False,
)
return
content = f'QA_RUNNER_OK:{text or "empty"}'
if 'stream' in text.lower():
for chunk in ('QA_', 'AGENT_', f'RUNNER_OK:{text}'):
yield RunnerResult.message_delta(
ctx.run_id,
MessageChunk(role='assistant', content=chunk),
)
yield RunnerResult.run_completed(ctx.run_id, finish_reason='stop')
return
yield RunnerResult.run_completed(
ctx.run_id,
Message(role='assistant', content=content),
finish_reason='stop',
)
@@ -1,5 +1,5 @@
apiVersion: langbot/v1
kind: AgentRunner
kind: Runner
metadata:
name: default
label:
@@ -27,4 +27,4 @@ spec:
execution:
python:
path: default.py
attr: DefaultAgentRunner
attr: DefaultRunner
@@ -3,6 +3,6 @@ from __future__ import annotations
from langbot_plugin.api.definition.plugin import BasePlugin
class QAAgentRunnerPlugin(BasePlugin):
class QARunnerPlugin(BasePlugin):
async def initialize(self) -> None:
self.ready_marker = "qa-agent-runner-ready"
self.ready_marker = 'qa-agent-runner-ready'
@@ -6,20 +6,20 @@ metadata:
repository: https://example.invalid/langbot/qa-agent-runner
version: 0.1.0
description:
en_US: Deterministic AgentRunner fixture for LangBot QA.
zh_Hans: LangBot QA 使用的确定性 AgentRunner 夹具。
en_US: Deterministic Runner fixture for LangBot QA.
zh_Hans: LangBot QA 使用的确定性 Runner 夹具。
label:
en_US: QA AgentRunner
zh_Hans: QA AgentRunner
en_US: QA Runner
zh_Hans: QA Runner
icon: assets/icon.svg
spec:
config: []
components:
AgentRunner:
Runner:
fromDirs:
- path: components/agent_runner/
- path: components/runner/
maxDepth: 1
execution:
python:
path: main.py
attr: QAAgentRunnerPlugin
attr: QARunnerPlugin