mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-06 22:06:03 +00:00
refactor(agent-runner): make agent binding and auth snapshot explicit
This commit is contained in:
@@ -41,9 +41,13 @@
|
||||
## 4. Event Envelope 与 Binding
|
||||
|
||||
- 入口事件用 `AgentEventEnvelope`(HOST_SDK §4.1)承载;顶层字段使用 LangBot 稳定协议名,平台原始事件名和原始 payload 放 `metadata` / `raw_ref`。
|
||||
- 触发关系用 `AgentBinding`(HOST_SDK §4.2)表达。EBA 阶段 binding 通过 `event_types`、`scope`、`filters` 决定哪些事件触发哪个 runner。
|
||||
- 触发关系用 `AgentBinding`(HOST_SDK §4.2)表达。EBA 阶段 binding 通过 `event_types`、`scope`、`filters` 决定哪些事件触发当前 bot / channel 绑定的 Agent。
|
||||
|
||||
Binding scope 示例:workspace 全局、bot 级、platform channel 级、conversation / group / thread 级、user / actor 级。旧 Pipeline 可迁移为 `message.received` 的 binding source,但不是唯一 binding source。
|
||||
目标产品语义:一个 bot / IM channel 在同一时间只绑定一个负责 agentic
|
||||
处理的 Agent;一个 Agent 可以被多个 bot / channel 复用。因此 EBA 主线按
|
||||
single-agent dispatch 设计,不做默认 fan-out。
|
||||
|
||||
Binding scope 示例:workspace 全局、bot 级、platform channel 级、conversation / group / thread 级、user / actor 级。旧 Pipeline 可迁移为 `message.received` 的临时 binding source,但目标持久配置应是 Agent,不是 Pipeline。
|
||||
|
||||
Event Source 可包括:`platform_adapter`(飞书、QQ、微信、Telegram 等)、`webui`、`http_api`、`scheduler`、`system`。EventRouter 不应写死平台 adapter 的类名。
|
||||
|
||||
@@ -53,7 +57,7 @@ Event Source 可包括:`platform_adapter`(飞书、QQ、微信、Telegram
|
||||
Platform Adapter / WebUI / API
|
||||
-> Event Gateway normalize payload
|
||||
-> EventLog append raw event
|
||||
-> EventRouter resolve bindings
|
||||
-> EventRouter resolve one effective AgentBinding
|
||||
-> AgentRunOrchestrator.run(event, binding)
|
||||
-> AgentRunContextBuilder.build(event, binding)
|
||||
-> PluginRuntimeConnector.run_agent()
|
||||
@@ -63,6 +67,10 @@ Platform Adapter / WebUI / API
|
||||
|
||||
约束:必须复用现有 orchestrator,不能为 EBA 单独实现另一套 plugin runner 调用协议;非消息事件不能绕过 resource authorization;delivery 和 platform action 走统一权限模型;外部 harness runner 也通过同一套 envelope/binding/context/result 协议接入,不为 Claude Code / Codex / Kimi 单独发明队列协议。
|
||||
|
||||
若未来产品需要 observer agent、多个 agent 并行处理同一事件、或多 runner
|
||||
裁决,应另行设计 fan-out 合并、delivery 冲突、state 写入冲突、platform
|
||||
action 审批和 audit 语义。当前 EBA 预留不隐含这些能力。
|
||||
|
||||
## 6. 平台动作执行
|
||||
|
||||
EBA 后 `action.requested`(PROTOCOL_V1 §7.2,当前仅 telemetry 不执行)将用于请求 host 执行平台动作:
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
LangBot 要转为 agent host,而不是内置 runner 容器:
|
||||
|
||||
- 接收 IM、WebUI、API 和未来 EventRouter 产生的事件。
|
||||
- 根据事件、bot、workspace、scope 解析应该调用的 agent binding。
|
||||
- 根据事件、bot、workspace、scope 解析应该调用的 Agent / agent binding。
|
||||
- 发现、校验和调用插件提供的 AgentRunner。
|
||||
- 为每次 run 提供受限资源、状态、存储、上下文引用和生命周期控制。
|
||||
- 接收 AgentRunner 返回的事件流,投递到 IM、WebUI 或其他 output surface。
|
||||
@@ -53,7 +53,12 @@ AgentRunResult stream
|
||||
Delivery / Renderer / Platform API
|
||||
```
|
||||
|
||||
当前 Pipeline 只应接入在 Query entry adapter 位置:它可以继续产生 `message.received`,但不应再拥有 runner 选择、上下文裁剪和业务 agent 执行的核心语义。EventGateway 由外部 event branch 实现。
|
||||
目标产品模型中,Agent 替代 Pipeline 承载 agent 配置:bot / IM
|
||||
channel 绑定一个 Agent,一个 Agent 可以被多个 bot / channel 复用。
|
||||
当前 Pipeline 只应接入在 Query entry adapter 位置:它可以继续产生
|
||||
`message.received` 并投影出临时 `AgentBinding`,但不应再拥有 runner
|
||||
选择、上下文裁剪和业务 agent 执行的核心语义。EventGateway 由外部 event
|
||||
branch 实现。
|
||||
|
||||
## 4. LangBot 侧能力
|
||||
|
||||
@@ -87,7 +92,11 @@ class AgentEventEnvelope(BaseModel):
|
||||
|
||||
### 4.2 AgentBinding
|
||||
|
||||
`AgentBinding` 是"什么事件调用哪个 runner、带什么绑定配置"的持久配置,是 Host 内部模型(不暴露给 SDK),替代长期依赖 Pipeline runner config 的角色。
|
||||
`AgentBinding` 是"什么事件调用哪个 AgentRunner、带什么 Agent 配置"的
|
||||
Host 内部运行投影(不暴露给 SDK)。产品层的持久对象应是 Agent:
|
||||
Agent 携带 runner id、runner config、resource/state/delivery policy,并可被
|
||||
多个 bot / channel 复用。`AgentBinding` 是 EventRouter / 当前
|
||||
QueryEntryAdapter 在一次运行前解析出的有效绑定。
|
||||
|
||||
```python
|
||||
class AgentBinding(BaseModel):
|
||||
@@ -103,16 +112,25 @@ class AgentBinding(BaseModel):
|
||||
delivery_policy: DeliveryPolicy
|
||||
```
|
||||
|
||||
**当前 adapter source**:`QueryEntryAdapter.config_to_binding(query, runner_id)` 从 current config 生成临时 `AgentBinding`。Pipeline 当前作为一种 binding source(AI runner config → binding、extension preference → resource_policy、output settings → delivery_policy),但新设计不再把这些字段命名为 Pipeline 专属概念。
|
||||
一个 bot / IM channel 在同一时间只应解析出一个负责 agentic 处理的
|
||||
AgentBinding。若未来需要 observer / fan-out / 多 agent 裁决,必须另行定义
|
||||
delivery、state、platform action 和 result 合并语义;当前 v1/EBA 主线不隐式支持。
|
||||
|
||||
**当前 adapter source**:`QueryEntryAdapter.config_to_agent_config(query, runner_id)`
|
||||
先把 current config 投影为迁移期 `AgentConfig`,再由
|
||||
`AgentBindingResolver.resolve_one(event, [agent_config])` 解析出唯一
|
||||
`AgentBinding`。Pipeline 当前只是迁移期 Agent config source(AI runner config
|
||||
→ runner_config、extension preference → resource_policy、output settings →
|
||||
delivery_policy),但新设计不再把这些字段命名为 Pipeline 专属概念。
|
||||
|
||||
### 4.3 AgentRunnerRegistry
|
||||
|
||||
Registry 收集 runner descriptor(来自插件 runtime、可能的 host adapter runner、开发期本地插件):
|
||||
Registry 收集 runner descriptor(来自插件 runtime、开发期本地插件):
|
||||
|
||||
```python
|
||||
class AgentRunnerDescriptor(BaseModel):
|
||||
id: str
|
||||
source: Literal["plugin", "host_adapter"]
|
||||
source: Literal["plugin"]
|
||||
label: I18nObject
|
||||
description: I18nObject | None = None
|
||||
protocol_version: str = "1"
|
||||
@@ -124,6 +142,10 @@ class AgentRunnerDescriptor(BaseModel):
|
||||
|
||||
职责:调用 `plugin_connector.list_agent_runners()` 拉取 runner、校验 manifest(`kind == AgentRunner`、`metadata.name/label` 存在、`protocol_version` 兼容、`spec.*` 类型正确)、输出 descriptor、缓存 discovery 结果并提供 `refresh()`。单个插件 manifest 失败只记 warning,不影响其它 runner。`plugin:author/name/runner` 是稳定 id 格式;多个 binding 指向同一 runner id 时**不创建多个插件实例**。
|
||||
|
||||
Host 内置 runner / adapter 不能作为 `AgentRunnerDescriptor.source` 绕过插件
|
||||
runtime、`run_id`、`ctx.resources` 和 `AgentRunAPIProxy` 权限链。若需要
|
||||
开发期调试 adapter,应放在 Host 内部测试入口,不进入可选 runner 列表。
|
||||
|
||||
刷新触发点:插件安装/卸载/升级/重启后;Pipeline metadata 请求时发现缓存为空;可选 TTL(优先保证正确性)。
|
||||
|
||||
### 4.4 AgentRunOrchestrator
|
||||
@@ -154,7 +176,14 @@ LangBot 在每次 run 前生成 `ctx.resources`(PROTOCOL_V1 §6),来自三
|
||||
2. binding / resource policy 允许的资源范围。
|
||||
3. 当前 event / actor / bot / workspace 的实际权限。
|
||||
|
||||
运行期每个 proxy action 必须再次通过 `run_id` 校验。SDK 侧本地校验只用于开发体验,host 侧校验才是安全边界。
|
||||
这次裁剪结果必须冻结为 run-scoped authorization snapshot,并由
|
||||
`AgentRunSessionRegistry` 按 `run_id` 保存。`ctx.resources` 是投影给 runner
|
||||
看的同一份授权结果;运行期每个 proxy action 只依据该 snapshot 校验 active
|
||||
run session、caller plugin identity、resource id、scope、payload size、rate
|
||||
limit 和 deadline。Handler 不应重新执行三层裁剪,否则 build-time 与 runtime
|
||||
授权逻辑会漂移。
|
||||
|
||||
SDK 侧本地校验只用于开发体验,host 侧 run authorization snapshot 才是安全边界。
|
||||
|
||||
资源裁剪应通用,不写死 local-agent。selector 与资源的映射示例:`model-fallback-selector` → primary/fallback LLM、`llm-model-selector` → LLM、`rerank-model-selector` → rerank 模型、`knowledge-base-multi-selector` → 知识库;新增 selector 时在 resource builder 中统一扩展。
|
||||
|
||||
|
||||
@@ -111,7 +111,11 @@ Claude Code、Codex、Kimi Code 这类 runner 不一定通过 LangBot 的模型/
|
||||
|
||||
## 7. Claude Code / Codex runner 当前形态
|
||||
|
||||
`claude-code-agent` 与 `codex-agent` 是最小可运行 MVP,用来证明外部 harness runner 可以接入同一套 AgentRunner 协议。本地 smoke 验收记录见 [PROGRESS.md](./PROGRESS.md) 与 [PHASE1_QA_ACCEPTANCE_MATRIX.md](./PHASE1_QA_ACCEPTANCE_MATRIX.md)。
|
||||
`claude-code-agent` 与 `codex-agent` 是最小可运行 MVP / dev path,用来证明外部 harness runner 可以接入同一套 AgentRunner 协议。本地 smoke 验收记录见 [PROGRESS.md](./PROGRESS.md) 与 [PHASE1_QA_ACCEPTANCE_MATRIX.md](./PHASE1_QA_ACCEPTANCE_MATRIX.md)。
|
||||
|
||||
MVP 含义:已验证 event-first context、resource projection、result stream 和
|
||||
基础 resume state 可以跑通;不表示 Docker 生产部署、发布级执行隔离、
|
||||
workspace lifecycle、secret projection、团队级 audit 或 runtime sidecar 已完成。
|
||||
|
||||
### 7.1 Claude Code runner
|
||||
|
||||
@@ -127,7 +131,7 @@ Claude Code、Codex、Kimi Code 这类 runner 不一定通过 LangBot 的模型/
|
||||
|
||||
### 7.3 当前限制
|
||||
|
||||
不是发布级安全边界实现;默认只做本地 CLI 调用,不实现完整执行隔离或 workspace 生命周期;不实现 issue-centric 队列、复杂 workflow engine 或长期任务调度;Codex 仅验证协议形态,不代表 Codex 发布级能力或 Kimi runner 已完成。runtime 管控面方向见 [RUNTIME_CONTROL_PLANE_V2.md](./RUNTIME_CONTROL_PLANE_V2.md)。
|
||||
不是发布级安全边界实现;默认只做本地 CLI 调用,不实现完整执行隔离或 workspace 生命周期;不实现 issue-centric 队列、复杂 workflow engine 或长期任务调度;Docker 环境只能访问容器内 CLI 和凭据;Codex 仅验证协议形态,不代表 Codex 发布级能力或 Kimi runner 已完成。runtime 管控面方向见 [RUNTIME_CONTROL_PLANE_V2.md](./RUNTIME_CONTROL_PLANE_V2.md)。
|
||||
|
||||
## 8. 发布和安装策略
|
||||
|
||||
|
||||
@@ -33,7 +33,11 @@ Protocol v1 **不定义**:
|
||||
| AgentRunAPIProxy | AgentRunner 访问 Host 能力的受限 API。 |
|
||||
| AgentBinding | Host 内部的事件到 runner 绑定配置,不直接暴露给 SDK(见 HOST_SDK §4.2)。 |
|
||||
|
||||
`AgentBinding` 只影响 Host 构造出的 `ctx.config`、`ctx.resources`、`ctx.context` 和 `ctx.delivery`。SDK 不需要知道 binding 的持久化形态。
|
||||
产品层的 `Agent` 替代旧 Pipeline 承载 agent 配置:bot / IM channel
|
||||
绑定一个 Agent,一个 Agent 可以被多个 bot / channel 复用。Host 内部的
|
||||
`AgentBinding` 是一次事件运行前解析出的有效绑定,只影响 Host 构造出的
|
||||
`ctx.config`、`ctx.resources`、`ctx.context` 和 `ctx.delivery`。SDK 不需要知道
|
||||
Agent / binding 的持久化形态。
|
||||
|
||||
外部 harness runner(Claude Code、Codex、Kimi Code 等)也是 `AgentRunner`:它们消费 event-first `AgentRunContext`、返回 `AgentRunResult`,并通过 Host 授权的 state/storage/artifact API 保存跨轮次指针。它们内部可以继续使用自己的 session、tool loop、MCP、上下文压缩和权限模型。
|
||||
|
||||
@@ -492,7 +496,9 @@ Host 不负责业务编排:不拼接全量历史、不替 runner 做 prompt as
|
||||
|
||||
## 12. Pipeline Adapter 边界
|
||||
|
||||
Pipeline 是当前入口 adapter,不是协议中心。Query entry adapter 负责:
|
||||
Pipeline 是当前入口 adapter,不是协议中心。目标产品模型中 Agent 会替代
|
||||
Pipeline 承载 runner config、resource policy 和 delivery policy;当前 Query
|
||||
entry adapter 只是迁移桥。它负责:
|
||||
|
||||
- 从 `Query` 构造 `AgentEventContext` 和临时 `AgentBinding`(见 HOST_SDK §4.2)。
|
||||
- 从当前 Agent/runner config 构造 `ctx.config`。
|
||||
@@ -501,15 +507,25 @@ Pipeline 是当前入口 adapter,不是协议中心。Query entry adapter 负
|
||||
约束:
|
||||
|
||||
- adapter **不**定义历史窗口、prompt 组装或 agentic context 策略。
|
||||
- preprocessing / hook 后的有效指令不通过 `ctx.adapter.extra` 主动推送;后续应通过 Host prompt/instruction pull API 暴露(占位见 HOST_SDK §4.8)。
|
||||
- `ctx.adapter.extra` 只允许承载一次性、JSON-safe、入口相关的非核心元数据,例如 `params`;不得承载 `prompt`、history window、RAG 结果、tool schema 或授权资源。
|
||||
- 静态绑定 prompt 属于 `ctx.config.prompt`。preprocessing / hook 后的动态有效指令不通过 `ctx.adapter.extra` 主动推送;后续如需要保留这类能力,应通过 Host prompt/instruction pull API 暴露(占位见 HOST_SDK §4.8)。
|
||||
- 新 runner 不应长期依赖 `adapter`,应只依赖 event-first context 和 Host API。
|
||||
|
||||
## 13. 开放问题
|
||||
## 13. 已确认约束
|
||||
|
||||
- v1 / EBA 主线是 `one event -> one AgentBinding -> one run_id -> one runner`。
|
||||
- 一个 bot / IM channel 在同一时间只绑定一个负责 agentic 处理的 Agent;一个 Agent 可以被多个 bot / channel 复用。
|
||||
- 如果配置层出现多个匹配 AgentBinding,BindingResolver 必须按明确规则选出一个或拒绝配置,不应默认 fan-out。
|
||||
- observer agent、多 runner fan-out、并行裁决、result 合并等能力需要单独设计 delivery、state、platform action 和 audit 语义,不属于当前 v1 契约。
|
||||
- `AgentRunnerDescriptor.source` 只允许 `plugin`;Host 内置 adapter 不能作为 runner source 绕过插件/runtime/proxy 权限链。
|
||||
- `ctx.resources` 与 proxy action 校验必须来自同一个 run authorization snapshot;runtime handler 不应重新执行资源裁剪。
|
||||
- 外部 harness runner 当前是 MVP / dev path,证明协议可接入,不代表发布级安全边界或 Docker 生产可用性完成。
|
||||
|
||||
## 14. 开放问题
|
||||
|
||||
- `AgentBinding` 是否需要进入 SDK 文档作为只读诊断信息,还是完全 Host 内部。
|
||||
- `TranscriptItem` 的最小字段集如何定义。
|
||||
- ArtifactStore 是否复用现有 BinaryStorage backend,还是引入独立实体。
|
||||
- State 与 Storage 的边界是否需要更强类型。
|
||||
- `platform_api` action 的审批模型如何表达。
|
||||
- 多 runner 并发处理同一 event 时,result delivery 的冲突策略如何定义。
|
||||
- Host 侧 scoped MCP / skill / workspace projection 是否需要从 runner config 上移为一等 resource projection API。
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
**本分支目标:AgentRunner 外化 / 插件化基础设施**
|
||||
|
||||
本分支只做 LangBot 作为 Agent Host 的基础能力建设:
|
||||
本分支只做 LangBot 作为 Agent Host 的基础能力建设,为后续用 `Agent`
|
||||
替代 Pipeline 承载 agent 配置打底:
|
||||
|
||||
- LangBot 与 SDK 的稳定协议合同(Protocol v1)
|
||||
- Host-side `AgentEventEnvelope` / `AgentBinding` 模型
|
||||
@@ -35,6 +36,22 @@
|
||||
|
||||
EventGateway 在本文档中描述为 **future integration point**,由外部 event branch 提供。本分支只定义 host-side envelope/binding models 和 `run(event, binding)` orchestrator 入口。
|
||||
|
||||
## 目标产品模型
|
||||
|
||||
未来产品层应把 `Agent` 理解为 Pipeline 的替代物:原先 bot 绑定
|
||||
Pipeline,Pipeline 携带 agent/provider/RAG/tool 等配置;后续应改为 bot 或
|
||||
IM channel 绑定一个 Agent,Agent 携带 runner id、runner config、
|
||||
resource/state/delivery policy 等 agent 配置。
|
||||
|
||||
约束:
|
||||
|
||||
- 一个 bot / IM channel 在同一时间只绑定一个负责 agentic 处理的 Agent。
|
||||
- 一个 Agent 可以被多个 bot / channel 复用,类似旧 Pipeline 可被多个 bot 共享。
|
||||
- Agent 配置是运行绑定配置,不是插件实例状态;多个 Agent 指向同一
|
||||
AgentRunner 时不创建多个插件实例。
|
||||
- 当前 Pipeline path 只是迁移期入口 adapter:它把旧 Pipeline 配置投影为临时
|
||||
`AgentBinding`,不代表目标架构仍由 Pipeline 承载 agent 语义。
|
||||
|
||||
## 当前状态
|
||||
|
||||
**当前 Pipeline 是入口 adapter,不再是 agent runner 设计核心。**
|
||||
@@ -65,7 +82,7 @@ EventGateway 在本文档中描述为 **future integration point**,由外部 e
|
||||
|
||||
- LangBot 与 SDK 的稳定协议合同
|
||||
- runner manifest / descriptor / registry
|
||||
- agent binding 与配置解析
|
||||
- Agent / binding 配置解析
|
||||
- run orchestration 和生命周期管理
|
||||
- resource authorization 与 `run_id` 级权限校验
|
||||
- host-owned state / storage / event log / transcript / artifact 能力
|
||||
@@ -87,6 +104,10 @@ Host 不定义通用历史窗口字段或策略;runner 通过 Host pull API
|
||||
|
||||
消息只是事件的一种。后续 `message.received`、`message.recalled`、`group.member_joined`、`friend.request_received` 等事件都应能通过统一事件 envelope 触发 AgentRunner。
|
||||
|
||||
EBA 主线按单 Agent 调度设计:EventRouter 对一个 bot / channel / scope
|
||||
解析出一个有效 AgentBinding,再调用一次 `AgentRunOrchestrator.run(event,
|
||||
binding)`。多 agent fan-out、observer agent 或并行裁决不属于当前目标语义。
|
||||
|
||||
**本分支不实现 EBA 完整能力,只预留:**
|
||||
- event-first envelope (`AgentEventEnvelope`)
|
||||
- AgentBinding model
|
||||
@@ -116,9 +137,11 @@ Host 不定义通用历史窗口字段或策略;runner 通过 Host pull API
|
||||
|
||||
- 一个插件可以声明多个 `AgentRunner` 组件,每个组件独立暴露 manifest、配置 schema、能力和权限。
|
||||
- 插件本身按单实例、无状态执行单元理解;不同绑定不创建多个插件实例。
|
||||
- 绑定只保存 runner id 和绑定配置,不代表插件实例状态。
|
||||
- Agent / binding 只保存 runner id 和绑定配置,不代表插件实例状态。
|
||||
- bot / IM channel 绑定一个 Agent;Agent 可被多个 bot / channel 复用。
|
||||
- LangBot 可以提供 host-owned state / storage 能力,让 runner 把状态寄宿在 LangBot;但这应该是授权能力,不是强制要求。
|
||||
- 官方 runner 插件是协议消费者,不是协议设计的优先约束。
|
||||
- Pipeline 是当前入口 adapter,不是未来架构中心。
|
||||
- Event dispatch 主线是 one event -> one AgentBinding -> one run_id -> one runner。
|
||||
- EventGateway 是 future integration point,由外部 event branch 提供。
|
||||
- Runtime control plane 是 v2 Host capability layer,不阻塞当前 AgentRunner v1 主线;agent 管控面插件应构建在该 Host 能力层之上。
|
||||
|
||||
Reference in New Issue
Block a user