LangBot Runner 插件如何將 Claude Code 和 Codex 接入 WeChat、Lark 與 DingTalk
Put Claude Code and Codex Inside WeChat, Lark and DingTalk with LangBot Runner Plugins
LangBot 4.11 將 Runner 改為插件,用戶可在 pipeline 選用 Claude Code、Codex 等 Runner,並透過 WeChat Work、Lark 或 DingTalk 適配器接收聊天事件。
Scenario
A team already lives in Claude Code and Codex — repos, shell, MCP servers on their own machines. Colleagues should reach that same power from WeChat Work, Lark and DingTalk group chats, without a terminal.
On 4.10 that was awkward — not inbound: 4.10.11 already ships openclaw_weixin, lark, dingtalk under src/langbot/pkg/platform/sources/. The processing side was the wall: nine built-in runners under src/langbot/pkg/provider/runners/ (localagent.py, difysvapi.py, … weknoraapi.py), so adding Claude Code meant patching LangBot or wrapping the CLI in an HTTP service outside the bot.
4.11 flips that: a Runner is a plugin, and the platform is only the event source. Support depends on the adapter and platform — check the support matrix first.
How it works in 4.11
New in 4.11: the built-in runners are gone. src/langbot/pkg/provider/runners/ holds ten files at v4.10.11 and does not exist at v4.11.0; src/langbot/pkg/provider/ keeps only modelmgr/, session/, tools/ (git ls-tree, both revisions).
A Runner is a plugin component. The runtime reports installed plugins' runners over LIST_RUNNERS; the host discovers and caches them in RunnerRegistry (src/langbot/pkg/agent/runner/registry.py:20,24,152), generating ids as plugin:author/plugin_name/runner_name (src/langbot/pkg/agent/runner/id.py:24-27) and rejecting anything without that prefix (id.py:52-57; PROTOCOL_V1.md §13).
The manifest is the contract: id, name, label, description, capabilities, permissions, config_schema, metadata (§4.2); capabilities is a typed boolean model for UI and resource projection, not a permission grant, and permissions is the access ceiling, intersected with the binding policy.
Official ids: plugin:langbot-team/ClaudeCodeAgent/default, plugin:langbot-team/CodexAgent/default (docs/agent-runner-pluginization/OFFICIAL_RUNNER_PLUGINS.md:33-34).
New in 4.11: the adapter layer. src/langbot/pkg/platform/adapters/ is absent at v4.10.11; 4.11 splits it into twelve packages with manifest.yaml, adapter.py, event_converter.py, and the Lark manifest declares kind: MessagePlatformAdapter (src/langbot/pkg/platform/adapters/lark/manifest.yaml:1-4,13). The inbound file inventory is unchanged: between v4.10.11 and v4.11.0, all 22 files under src/langbot/pkg/platform/sources/ are modifications — no additions, no deletions — so no new platform arrived here.
Where config lands: ai.runner.id stores the runner id and ai.runner_config[<runner_id>] its settings (src/langbot/templates/metadata/pipeline/ai.yaml:6-18), so switching runners keeps earlier settings.
Hands-on steps
Runner plugins execute in a separate plugin-runtime container, so this is a two-container setup (local demo values — replace them):
docker network create lang7-411
docker run -d --name lang7-411-core --network lang7-411 -e BOX__ENABLED=false \
-p 15400:5300 -v "$PWD/deploy/411/data:/app/data" rockchin/langbot:v4.11.0
docker run -d --name lang7-411-runtime --network lang7-411 --network-alias langbot_plugin_runtime \
-v "$PWD/deploy/411/data/plugins:/app/data/plugins" \
rockchin/langbot:v4.11.0 uv run --no-sync -m langbot_plugin.cli.__init__ rt
The admin account starts as admin@langbot.local; the password is a local demo value — replace it.
Step 1 — install from the marketplace. UI: Extensions → Extension Marketplace (web/src/i18n/locales/zh-Hans.ts:337-341); CLI: POST /api/v1/plugins/install/marketplace with {plugin_author, plugin_name}, returning {task_id} for task plugin-install-marketplace; the record carries install_source=marketplace (src/langbot/pkg/api/http/controller/groups/plugins.py:923-960). Here we installed langbot-team/LocalAgent; the Claude Code and Codex plugins use the same door (repo langbot-plugins, Runner/claude-code-agent, Runner/codex-agent).
Step 2 — confirm where it landed. The artifact is not in the mounted plugins/ directory but inside the runtime container at /app/data/plugin-runtime/artifacts/sha256/<digest>/code/ (manifest.yaml, main.py, pkg/, components/, CERTIFICATION.md), while the host-mounted plugins/ stays empty (observed 2026-10-16); <digest> is the recorded artifact_digest. Three checks: the API (GET /api/v1/plugins returns a {plugins: [...]} array containing it, plugins.py:387-397); the database (a plugin_settings row holding artifact_digest, runtime_revision, install_source, enabled, src/langbot/pkg/entity/persistence/plugin.py:12-35,46-51); and the logs — Mounting plugin langbot-team/LocalAgent... → Initializing Runner component: default → Component default initialized, instance type: DefaultRunner (observed 2026-10-16). The point: the runtime instantiates a component instance and the Runner capability hangs off it.
Step 3 — pick the Runner in the pipeline. In the pipeline editor open AI capabilities (web/src/i18n/locales/zh-Hans.ts:1941) and find the stage card labelled "运行方式" (src/langbot/templates/metadata/pipeline/ai.yaml:7-9) with its required "运行器" dropdown (:14-18). The value is the full runner id, e.g. plugin:langbot-team/LocalAgent/default; for Claude Code, plugin:langbot-team/ClaudeCodeAgent/default. Here the LocalAgent block at ai.runner_config[<runner_id>] read timeout: 300, max-tool-iterations: 100 (observed 2026-10-16).
Step 4 — connect the chat platform as an event source. Connect a WeChat Work, Lark or DingTalk adapter; events arrive, event bindings route them into a pipeline, and the selected Runner does the work — one bot, several pipelines, each free to use a different Runner.
Claude Code and Codex settings come from their READMEs: command defaults to claude / codex, timeout to 300 / 1800 seconds, plus workspace, ssh-target, mcp-servers-json (Runner/claude-code-agent, Runner/codex-agent).
Verify
API: GET /api/v1/plugins contains langbot-team/LocalAgent with enabled true. Database: digest and revision persisted — values observed here:
SELECT plugin_author, plugin_name, artifact_digest, runtime_revision, install_source, enabled
FROM plugin_settings;
-- langbot-team|LocalAgent|2d2ce17055d70dd7736e6902595be3262992fd1598a00bd9d79d19fef1c16329|1|marketplace|1
Runtime container: the same ls shows the files listed above while the host-mounted plugins/ stays empty; an empty result means the wrong layer. Pipeline: ai.runner.id must start with plugin: (web/src/app/home/pipelines/pipeline-config-safety.ts:7-25) and ai.runner_config must hold an object keyed by that id. Then send a real message and confirm the reply comes from the installed Runner.
Limits and caveats
-
The platform is only an event source. The inbound
src/langbot/pkg/platform/sources/file set matches 4.10.11 — all 22 files are modifications, none added or removed — and what 4.11 adds is theplatform/adapters/event-adapter layer; the adapter plus the event binding decides whether a platform works, not the Runner. The support matrix in 01-event-system.md is a preliminary assessment, per the doc. -
Marketplace installs need egress. The archive is fetched from
{space_url}/api/v1/marketplace/plugins/download/{author}/{name}/{version}(src/langbot/pkg/plugin/connector.py:1795-1797); installs from GitHub or a local archive recordgithub/local. -
Artifacts are content-addressed. The marketplace-side digest need not equal your local one; compare with
plugin_settings.artifact_digest— here the two LocalAgent 0.2.1 digests differ (observed 2026-10-16). -
The external CLI runners are permissive by default.
ClaudeCodeAgentdefaultsdangerously-skip-permissionstotrue(falserestores Claude Code's own checks; LangBot has no interactive approval flow today) andCodexAgenttoapproval-policy=never/sandbox-mode=danger-full-access. Trusted workspaces only. -
Interaction is not a hanging wait. Both CLI runners turn requests such as
ask_user_questionintointeraction.requestedfor the adapter to render as a card; the CLI stops while the user answers, and the answer starts a new run resuming the same session. -
The harness path is an MVP. The protocol doc states an external harness runner is currently an MVP / dev path: proof the protocol can be wired up, not a release-grade security boundary or finished Docker deployability (
PROTOCOL_V1.md§13). -
Certification fields can disagree. Here
install_info._certificationreadverification: "invalid"withcertificate_id: null, while the marketplace reportedcertificate_status: "issued"— do not assume local verification passed because a plugin is listed (see article 4).
Summary and next steps
In 4.11 a Runner is not shipped with LangBot but installed from the marketplace, configured in the app, selected per pipeline. The platform delivers the event; the Runner decides how it is processed — a local CLI agent (Claude Code, Codex, ACP) or a service runner such as Dify, Coze, n8n, Langflow or DeerFlow.
Primary reference: the pinned migration doc pipeline-migration-config-map.zh-CN.md, which also lists the minimum Runner plugin versions the migrator requires; the v4.11.0 release page has the notes. Plugins are also listed in Runner/ in langbot-plugins.
Next: if your instance was upgraded from 4.10, that old config landing in the new shape is article 3 — the migration touches ai.runner.runner, ai.runner.id and ai.runner_config together. For a hosted environment, Cloud is worth a separate look (https://space.langbot.app).
來源:DEV Community · dev.to


