Skip to content

Feat/agent runner plugin#2260

Closed
huanghuoguoguo wants to merge 8 commits into
masterfrom
feat/agent-runner-plugin
Closed

Feat/agent runner plugin#2260
huanghuoguoguo wants to merge 8 commits into
masterfrom
feat/agent-runner-plugin

Conversation

@huanghuoguoguo

@huanghuoguoguo huanghuoguoguo commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

状态 / Status

QA 完成,验收标准 5/5 通过。 合并顺序 / merge order:先合 SDK PR #82 并发布新 SDK 版本 → bump 本仓库 pyproject.tomllangbot-plugin pin → 再合本 PR。

关联 PR / Related PR

关联测试仓库 / Related Testing Repositories

概述 / Overview

把 LangBot 技能统一为授权工具(skill all-tool model)。技能不再藏在 skill_authoring capability 之后;activate / register_skill / 原生 exec 像普通工具一样暴露,仅受 sandbox + skill_mgr 控权。发现走工具化(langbot_list_assets 新增 skills 资产类,供外部 harness 使用)。Host 持久化已激活技能(host.activated_skills,last-write-wins),并预填 ToolResource.parameters 让 runner 跳过逐工具 get_tool_detail

Unifies LangBot skills as authorized tools: skills are no longer gated behind skill_authoring; activate / register_skill / native exec are exposed like native tools, gated only on sandbox + skill_mgr. Discovery is tool-driven (langbot_list_assets gains a skills asset class). The host persists activated skills and prefills ToolResource.parameters.

主要改动(host 侧)/ Key host-side changes:

  • toolmgr / SkillToolLoader:去掉 include_skill_authoring,自闸于 sandbox+skill_mgr
  • preproc / resource_builder:技能 gate 改为 skill_mgr,并预填 ToolResource.parameters
  • 持久化已激活技能到 host.activated_skills(conversation scope)

验收 / QA — 5/5 通过

  1. 单元矩阵全绿(host / sdk / local-agent),0 新失败
  2. 技能工具暴露(无需 skill_authoring)/ 激活持久化 / 参数预填 — 单元覆盖
  3. 沙箱技能端到端 OPERATE — nsjail + docker 均通过:完整 create→exec→register→activate→在 /workspace/.skills/<name> exec 链路全 exit 0;激活技能的 scripts/use.py 读到 data/input.json、写回文件穿透回 host 技能 store
  4. skill-discovery-via-mcp-gateway — claude-code + acp 两个外部 harness 经 MCP gateway 均发现技能
  5. 跨 runner parity — local-agent / claude-code / acp 各自路径均触达技能

完整验收矩阵:skills/skills/langbot-testing/references/skill-all-tool-acceptance.md

#2271

激活技能在 docker 上 scripts//data/ 缺失。根因更正:不是"docker 屏蔽嵌套挂载",而是容器复用 —— extra_mounts 未纳入 box session 兼容性检查,技能中途激活时 docker 复用运行中容器、无法追加 bind mount。由 SDK #87(挂载集合变化时重建容器)修复,已 rebase 进 #82。修复后 docker 端到端通过。

检查清单 / Checklist

PR 作者完成 / For PR author

  • 阅读仓库贡献指引了吗? / Have you read the contribution guide?
  • 与项目所有者沟通过了吗? / Have you communicated with the project maintainer?
  • 我确定已自行测试所作的更改,确保功能符合预期。 / I have tested the changes and ensured they work as expected.

项目维护者完成 / For project maintainer

  • 相关 issues 链接了吗? / Have you linked the related issues?
  • 配置项写好了吗?迁移写好了吗?生效了吗? / Have you written the configuration items? Have you written the migration? Has it taken effect?
  • 依赖加到 pyproject.toml 和 core/bootutils/deps.py 了吗 / Have you added the dependencies to pyproject.toml and core/bootutils/deps.py?
  • 文档编写了吗? / Have you written the documentation?

@huanghuoguoguo huanghuoguoguo added External Plugin 插件问题或新增插件 / Issues on plugin itself m: Plugins 插件加载及管理模块 / Plugins loading and management m: Lifecycle 启动/关闭流程 / Bootstrap & application life cycle eh: Feature enhance: 新功能添加 / add new features size:XXL This PR changes 1000+ lines, ignoring generated files. labels Jun 19, 2026
Comment on lines +18 to +36
from langbot.pkg.entity.persistence import (
agent_run, # noqa: F401
agent_runner_state, # noqa: F401
apikey, # noqa: F401
bot, # noqa: F401
bstorage, # noqa: F401
event_log, # noqa: F401
mcp, # noqa: F401
metadata, # noqa: F401
model, # noqa: F401
monitoring, # noqa: F401
pipeline, # noqa: F401
plugin, # noqa: F401
rag, # noqa: F401
transcript, # noqa: F401
user, # noqa: F401
vector, # noqa: F401
webhook, # noqa: F401
)
Comment thread tests/unit_tests/agent/test_event_first_protocol.py Fixed
@huanghuoguoguo huanghuoguoguo force-pushed the feat/agent-runner-plugin branch from 2e5244f to cede35b Compare June 20, 2026 12:12
@huanghuoguoguo huanghuoguoguo marked this pull request as ready for review June 20, 2026 12:44
Expose skill tools (activate/register_skill/native exec) like native tools
instead of gating them behind the skill_authoring capability:
- toolmgr.get_all_tools drops include_skill_authoring; SkillToolLoader
  self-gates on sandbox + skill_mgr
- preproc drops the include_skill_authoring branch; pipeline-bound skills
  and the skills resource gate on skill_mgr presence

Persist activated skills into host.activated_skills conversation state so
they survive across runs (host writes at activate; last-write-wins); drop
the dead restore_activated_skills helper.

Prefill ToolResource.parameters host-side (tool_mgr.get_tool_schema) so
runners build LLM tools without per-tool get_tool_detail round-trips.

Align agent-runner-pluginization design docs to the all-tool model.
- references/skill-all-tool-acceptance.md: acceptance matrix for the skill
  all-tool model (runner x lifecycle x backend), case status, exit criteria,
  and the #2271 known issue (pre-existing box nested-mount, not this branch)
- cases/skill-discovery-via-mcp-gateway.yaml: schema-valid case proving an
  external harness discovers skills via langbot_list_assets (the new 'skills'
  asset class); marked blocked-env until remote claude-code is responsive
@TyperBody

Copy link
Copy Markdown
Member

项目堆得怎摸样了 能跑了叫我一声 我堆几个agent runner

…rt finding

- claude-code-agent (new pipeline, remote-ssh->101): langbot_list_assets returns
  skills=1 tools=15 in 24s -> all-tool 'skills' asset class is discoverable
  end-to-end by an external harness on the unmodified branch
- document the runner transport difference: claude-code uses a stdio bridge
  (works on remote-ssh out of the box), acp uses an HTTP proxy (needs
  langbot-assets-gateway-public-url on remote-ssh). This is a runner-plugin
  detail, not a host all-tool-branch issue
…blic-url

Prior matrix recorded acp as blocked needing langbot-assets-gateway-public-url
(PROBEDONE 0 0 / timeout). That was an environment artifact: a duplicate
LangBot-master/ backend contending on box ws-control-port 5410 plus a wedged
plugin runtime (host emit_event / list_agent_runners timing out). On a clean
single-instance runtime acp discovers skills via the SDK SSH reverse tunnel
with no public-url: PROBEDONE 1 17 (8-24s), parity with claude-code (1 15).
…2271 fixed)

- nsjail: full create→exec→register→activate→exec-from-activated-path chain
  returns exit 0; activated mount runs scripts/use.py (reads data/input.json)
  and writes activated_writeback.txt through to the host skill store.
- docker: same chain now passes after langbot-plugin-sdk#87 (recreate sandbox
  container when extra_mounts change). Corrected #2271 root cause from
  'docker masks nested bind mount' to container-reuse: extra_mounts was not in
  the box session compatibility check, so docker reused a running container and
  could not append the activated skill's bind mount.
- Exit criterion 3 (real end-to-end skill use) now DONE; all 5 criteria met.
- Documents the nsjail stale-docker-artifact environment gotcha.
@huanghuoguoguo

Copy link
Copy Markdown
Collaborator Author

项目堆得怎摸样了 能跑了叫我一声 我堆几个agent runner

可以了,你试试

Extract the AgentRunner Protocol v1 host-side surface from the giant
RuntimeConnectionHandler.__init__ into sibling modules using a registration-
function pattern (behavior-preserving; @h.action == @self.action):

- agent_run_support.py: shared constants + authorization/scope/projection helpers
- agent_pull_actions.py: register(h) for history/event pull APIs
- agent_runner_actions.py: register(h) for run/runtime/stats/claim lifecycle
- agent_state_actions.py: register(h) for steering/state APIs

__init__ now calls the three register(self) functions. handler.py keeps the
pre-existing plugin/llm/vector/knowledge handlers, get_prompt/call_tool/
get_tool_detail (coupled to retained helpers), shared helpers, and outbound
methods; it re-imports _validate_agent_run_session so external imports keep
working. handler.py: 4066 -> 1871 lines.

test_state_api_auth.py: repoint get_session_registry patch targets to
agent_run_support (the lookup moved modules). 385 agent unit tests pass; ruff clean.
Drop the PluginToolLoader.get_tool() override that returned a raw
ComponentManifest, so every loader's get_tool() now returns a uniform
resource_tool.LLMTool (PluginToolLoader.get_tools() already did this
conversion). This removes the only source of tool-shape heterogeneity.

- ToolManager.get_tool_schema(): drop the ComponentManifest-vs-LLMTool branch
- ToolManager.get_tool_detail(): new host-level shape {name, description,
  human_desc, parameters}
- handler.py GET_TOOL_DETAIL: call tool_mgr.get_tool_detail(); delete the
  handler-local _build_tool_detail + _i18n_to_dict/_i18n_to_text adapters and
  the litellm TODO
- ToolLookupResult is now just LLMTool

The dropped label/spec fields were not consumed by any runner (local-agent
build_llm_tool and external harnesses use only name/description/parameters).
@RockChinQ

Copy link
Copy Markdown
Member

Continue in #2277

@RockChinQ RockChinQ closed this Jun 23, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

eh: Feature enhance: 新功能添加 / add new features External Plugin 插件问题或新增插件 / Issues on plugin itself m: Lifecycle 启动/关闭流程 / Bootstrap & application life cycle m: Plugins 插件加载及管理模块 / Plugins loading and management size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants