diff --git a/docs/liteflow-react-agent-guide.md b/docs/liteflow-react-agent-guide.md index dc11b4257..341cca1ae 100644 --- a/docs/liteflow-react-agent-guide.md +++ b/docs/liteflow-react-agent-guide.md @@ -118,9 +118,9 @@ - `ChatUsageTrackingHook` → `ChatUsageMiddleware`(在 `onModelCall` 后读 message usage 累加,**`ctx().getChatUsage()` API 保留**); - `SkillTrackingHook` → `SkillTrackingMiddleware`(在 `onActing` 监听 `load_skill_through_path` 工具调用,记录 `usedSkills()`)。 -业务侧 `hooks()` 返回 `List` 的写法**保留兼容**(内部经 `HookMiddlewareAdapter` 转 middleware),但方法标 `@Deprecated(forRemoval)`;**推荐改用 `middlewares()` 返回 `List`**。1.0 的 `Hook`(`io.agentscope.core.hook.Hook`)在 v2 软弃用但仍可编译运行。 +业务侧 `hooks()` 返回 `List` 的写法**保留兼容**(经 `ReActAgent.builder().hooks(...)` 直接桥接,`builder` 内部把 1.0 `Hook` 软适配为 v2 middleware;v2 `Hook` 软弃用但仍可编译运行),但方法标 `@Deprecated(forRemoval)`;**推荐新代码用 `middlewares()` 返回 `List`**。1.0 的 `Hook`(`io.agentscope.core.hook.Hook`)在 v2 软弃用但仍可编译运行。 -**`ctx().getChatUsage()` 的线程模型**:真实 vendor 模型下,`onModelCall` 在 `boundedElastic` 调度线程上被调用(不在 `process()` 的 HTTP 线程上)。ChatUsage 累加器走 **reactor `Context` 向上游传播**(`process()` 在订阅前 `contextWrite` 把累加器塞进 Context),保证任意调度线程上的 middleware 都能读到;同时保留 ThreadLocal 回退使无 reactor Context 的单元测试继续可用。1.0 的单线程 ThreadLocal 假设在 v2 不成立——若你自定义 middleware 累加 token,请走同样的 reactor Context 方案。 +**`ctx().getChatUsage()` 的线程模型**:真实 vendor 模型下,`onModelCall` 在 `boundedElastic` 调度线程上被调用(不在 `process()` 的 HTTP 线程上)。累计 per-invocation 状态的 middleware(`ChatUsageMiddleware` 累加 token、`SkillTrackingMiddleware` 记录 `usedSkills()`)均经 **reactor `Context` 向上游透传**(`Flux.deferContextual`,`process()` 在订阅前 `contextWrite` 把累加器/状态塞进 Context),保证任意调度线程上的 middleware 都能读到,跨 `boundedElastic` 线程安全;同时保留 ThreadLocal 回退使无 reactor Context 的单元测试继续可用。1.0 的单线程 ThreadLocal 假设在 v2 不成立——若你自定义 middleware 累加 token 或其它 per-invocation 状态,请走同样的 reactor Context 方案。 **流式**:`agent.stream(...)` → `agent.streamEvents(...)`(`Flux`,28 个类型化事件)。`AgentEventBridge` 把 v2 事件映射到 LiteFlow 对外 4 类 `FlowEvent` type(**type 字符串不变**,保下游兼容):`agent.reasoning` / `agent.tool_result` / `agent.summary` / `agent.result`,并可选透传 HITL 事件。没有注册 `ExecuteOption.eventListener(...)` 时仍走阻塞 `call()` 路径。详见 [§ 2.6 流式输出](#26-流式输出)。 @@ -138,7 +138,7 @@ - 自定义 `hooks()` 返回 `List`——保留兼容但标 `@Deprecated`,建议迁 `middlewares()`; - 依赖 workspace“每会话一目录”物理布局(自定义工具按 `/` 约定读写文件)——RC3 单根布局下需调整路径约定。 -> **源码兼容回归测试**:`liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/v2/BackCompatSmokeTest.java` 把“业务子类核心用法零改动可编译运行”做成回归用例——一个严格镜像 [§ 2.3](#23-编写-agent-组件) 范式的 `ReActAgentComponent` 子类(`model()` 返回 mock `ModelSpec` 产出 `CannedReplyModel`,避免真实凭据),最简 chain `THEN(agent)`,`execute2Resp` 执行,断言 success + `responseData` 非空。每次升级 agentscope 版本都应保证此测试绿。 +> **源码兼容回归测试**:`liteflow-testcase-el/liteflow-testcase-el-react-agent/src/test/java/com/yomahub/liteflow/test/agent/v2/BackCompatSmokeTest.java` 把“业务子类核心用法零改动可编译运行”做成回归用例——一个基于 [§ 2.3](#23-编写-agent-组件) 范式的 `ReActAgentComponent` 子类(在 § 2.3 示例基础上额外覆写 `enableReActLogging()` 等开关以演示能力声明,`model()` 返回 mock `ModelSpec` 产出 `CannedReplyModel`,避免真实凭据),最简 chain `THEN(agent)`,`execute2Resp` 执行,断言 success + `responseData` 非空。每次升级 agentscope 版本都应保证此测试绿。 ### 1.5.6 进一步阅读 @@ -369,7 +369,7 @@ if (response.isSuccess()) { `ReActAgentComponent#process()` 是 `final`。框架在其中统一完成配置读取、conversation 解析、`agentKey` 解析、Session 获取、加锁、Agent 懒构建、调用、回复处理和 memory 保存。业务侧通过覆写受保护方法定制行为。 > **2.0(RC3) 变化**:`process()` 内部已重写——不再手动 Session 获取/加锁/懒构建/memory 保存,改为构建无状态 `ReActAgent` 单例 + `RuntimeContext(userId=conversationId, sessionId=agentKey)` + `agent.call(...)`,由 v2 管 load/save/串行。受保护方法签名(下表)**保持不变**,仅以下几项语义微调: -> - `hooks()`:1.0 注册 agentscope `Hook`;RC3 标 `@Deprecated(forRemoval)`,内部经 `HookMiddlewareAdapter` 转 v2 `MiddlewareBase`。**推荐改用 `middlewares()` 返回 `List`**。 +> - `hooks()`:1.0 注册 agentscope `Hook`;RC3 标 `@Deprecated(forRemoval)`,经 `ReActAgent.builder().hooks(...)` 直接桥接(v2 `Hook` 软弃用但仍可编译运行)。**推荐新代码用 `middlewares()` 返回 `List`**。 > - `enableShellTool()` / `enableWorkspaceFileTools()`:签名保留,语义改为“是否在 `ReActAgent` 上启用对应工具组”(与 1.0 行为等价,shell 仍与 `shell.mode` 取逻辑与)。 > - `enableReActLogging()`:改为控制 `LoggingMiddleware` 是否安装(开关仍是 `logging.react-enabled`)。 > @@ -839,6 +839,8 @@ public class EncryptedFileSessionFactory implements AgentSessionFactory { ### 6.1 Workspace 目录结构 +> **2.0(RC3) 变化:** 下方“每个 conversation 一个 `/` 子目录”的布局是 **1.0 行为**,RC3-core 下已不适用——workspace 改为 `workspace.root` 单根 + conversationId 作为 v2 `userId` 维度命名(不再为每会话建独立子目录)。原描述保留作历史参考,详见 [§ 1.5](#15-从-10-升级到-agentscope-20rc3)。 + 每个 conversation 都会在 `liteflow.agent.workspace.root` 下获得一个独立子目录: ```text @@ -852,6 +854,8 @@ public class EncryptedFileSessionFactory implements AgentSessionFactory { ### 6.2 Workspace 配置 +> **2.0(RC3) 变化:** 下表中 `cleanup-on-session-expire` / `cleanup-on-jvm-shutdown` 绑定的是 1.0 已删除的 `AgentSessionManager.close()` / 空闲 AgentSession 过期语义,RC3-core 下随单根 workspace 一起**失效**;这两个键的清理语义将随 GA HarnessAgent 落地,详见 [§ 1.5](#15-从-10-升级到-agentscope-20rc3)。原描述保留作历史参考。 + | 配置项 | 默认值 | 说明 | | --- | --- | --- | | `root` | 无 | 必填,workspace 根目录 |