Skip to content

feat: dev snippet fronted#36772

Merged
FFXN merged 60 commits into
deploy/devfrom
feat/dev-snippet-fronted
May 28, 2026
Merged

feat: dev snippet fronted#36772
FFXN merged 60 commits into
deploy/devfrom
feat/dev-snippet-fronted

Conversation

@FFXN
Copy link
Copy Markdown
Contributor

@FFXN FFXN commented May 28, 2026

Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue and you have been assigned to it
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

Screenshots

Before After
... ...

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint && make type-check (backend) and cd web && pnpm exec vp staged (frontend) to appease the lint gods

lyzno1 and others added 30 commits May 26, 2026 02:33
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
…e group (#36595)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…§8) (#36644)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
… tests (#36658)

Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
…red (#36227)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: wangxiaolei <fatelei@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Signed-off-by: EvanYao826 <155432245+EvanYao826@users.noreply.github.com>
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. feat:webapp Ready-to-use AI web app. Also the "Preview" / "Debug & Preview" inside the orchestrate page. javascript labels May 28, 2026
@github-actions github-actions Bot added the web This relates to changes on the web. label May 28, 2026
@dosubot
Copy link
Copy Markdown

dosubot Bot commented May 28, 2026

Related Knowledge

1 document with suggested updates is ready for review.

dify

Dify Agent Server 模块分析 (Commit 55f95dbc)
View Suggested Changes
@@ -232,11 +232,11 @@
 
 [[23]](https://github.com/langgenius/dify/blob/7210f856c9c07ae03d7c2e5def96c949efee6397/dify-agent/src/dify_agent/layers/dify_plugin/plugin_layer.py)
 
-**`DifyPluginLayer`**(type_id: `dify.plugin`):共享的 Plugin Daemon 租户/用户上下文层,携带 `tenant_id` 和 `user_id`,不持有 HTTP 客户端。Plugin Daemon URL 和 API Key 由服务端 Provider 工厂注入,确保这些敏感配置不出现在公开的 HTTP 请求体中。该层作为共享依赖被 LLM 和工具层复用,具体的 `plugin_id` 由业务层(LLM、工具)各自携带 [[24]](https://github.com/langgenius/dify/blob/7210f856c9c07ae03d7c2e5def96c949efee6397/dify-agent/src/dify_agent/layers/dify_plugin/plugin_layer.py#L1-L11)。
-
-**`DifyPluginLLMLayer`**(type_id: `dify.plugin.llm`):依赖 `DifyPluginLayer`,持有插件包 ID(`plugin_id`)、模型提供者(`model_provider`)、模型名称(`model`)和模型凭证配置。其 `get_model()` 方法接受共享的 `httpx.AsyncClient`,返回 Pydantic AI 兼容的模型实例。
-
-**`DifyPluginToolsLayer`**(type_id: `dify.plugin.tools`):插件工具暴露层,将 API 侧预备的插件工具声明注册为 Pydantic AI 工具。API 侧负责解析 daemon 声明、合并参数和生成模型可见 JSON schema;Agent 侧负责验证隐藏输入、应用默认值、调用 daemon 并转换响应。配置包含工具列表(`DifyPluginToolConfig`),每个工具携带自己的 `plugin_id`、提供者名称(`provider`)、daemon 工具名称(`tool_name`)、凭证类型(`credential_type`)、运行时隐藏参数(`runtime_parameters`)以及 API 预备的参数声明(`parameters`、`parameters_json_schema`)。
+**`DifyExecutionContextLayer`**(type_id: `dify.execution_context`):Dify 执行上下文层,携带 `tenant_id`、`user_id`、`app_id`、`workflow_id`、`workflow_run_id`、`node_id`、`conversation_id`、`agent_id`、`agent_config_version_id` 等运行时标识。不持有 HTTP 客户端。Plugin Daemon URL 和 API Key 由服务端 Provider 工厂注入。该层作为共享依赖被 LLM 和工具层复用,确保上下文不出现在公开的 HTTP 请求体中。
+
+**`DifyPluginLLMLayer`**(type_id: `dify.plugin.llm`):依赖 `DifyExecutionContextLayer`,持有插件包 ID(`plugin_id`)、模型提供者(`model_provider`)、模型名称(`model`)和模型凭证配置。其 `get_model()` 方法接受共享的 `httpx.AsyncClient`,返回 Pydantic AI 兼容的模型实例。
+
+**`DifyPluginToolsLayer`**(type_id: `dify.plugin.tools`):插件工具暴露层,依赖 `DifyExecutionContextLayer`,将 API 侧预备的插件工具声明注册为 Pydantic AI 工具。API 侧负责解析 daemon 声明、合并参数和生成模型可见 JSON schema;Agent 侧负责验证隐藏输入、应用默认值、调用 daemon 并转换响应。配置包含工具列表(`DifyPluginToolConfig`),每个工具携带自己的 `plugin_id`、提供者名称(`provider`)、daemon 工具名称(`tool_name`)、凭证类型(`credential_type`)、运行时隐藏参数(`runtime_parameters`)以及 API 预备的参数声明(`parameters`、`parameters_json_schema`)。
 
 #### 4. Output Layer
 
@@ -1291,3 +1291,164 @@
 ```
 
 这一集成建立了**数据库持久化的 Agent 身份系统**(Agent Roster)和**工作流可引用的配置版本机制**,使 Agent 配置从"一次性请求负载"演进为"版本化、可审计、可复用的领域资产"。
+
+## PR #36772 - 架构改进与新增功能
+
+**[PR #36772 `Feat: dev snippet fronted`](https://github.com/langgenius/dify/pull/36772)** 于 2026-05-28 合并,在已有 Agent 后端基础上引入了重大架构改进和多项新功能。主要变更涵盖 Layer 依赖结构重构、插件工具构建器、会话清理机制、节点输出检查器等模块。
+
+### Layer 架构重构
+
+#### 执行上下文层独立
+
+`DIFY_PLUGIN_CONTEXT_LAYER_ID` 被重命名为 `DIFY_EXECUTION_CONTEXT_LAYER_ID`,对应的 Layer 从 `DifyPluginLayer`(`dify.plugin`)改为 `DifyExecutionContextLayer`(`dify.execution_context`)。新的执行上下文层携带 Dify 运行时标识(`tenant_id`、`user_id`、`app_id`、`workflow_id`、`workflow_run_id`、`node_id`、`conversation_id`、`agent_id`、`agent_config_version_id` 等),不持有插件相关配置。
+
+#### 凭证分离到专用层
+
+LLM 和工具的凭证现已分别隔离到各自的 Layer 中:
+- **LLM 凭证**:`DIFY_PLUGIN_LLM_LAYER_TYPE_ID`(`dify.plugin.llm`)
+- **工具凭证**:`DIFY_PLUGIN_TOOLS_LAYER_TYPE_ID`(`dify.plugin.tools`)
+
+这两个 Layer 现在都直接依赖 `execution_context` 层,而非旧版的 `plugin` 层。`AgentBackendModelConfig` 移除了 `tenant_id` 和 `user_id` 字段,这些信息改由 `DifyExecutionContextLayerConfig` 携带。`DifyPluginLLMLayerConfig` 新增 `plugin_id` 字段(之前由父层提供)。
+
+#### 历史层可选控制
+
+`AgentBackendWorkflowNodeRunInput` 新增 `include_history: bool = True` 字段,用于控制是否在请求中包含 `pydantic_ai.history` 层(type_id: `PYDANTIC_AI_HISTORY_LAYER_TYPE_ID`,保留 ID: `DIFY_AGENT_HISTORY_LAYER_ID`)。当 `include_history=True` 时,历史层按标准 layer 构造插入到 execution_context 层之后、model 层之前;否则跳过。
+
+#### 退出策略默认值调整
+
+`AgentBackendWorkflowNodeRunInput.suspend_on_exit` 的默认值从 `False` 改为 `True`,意味着工作流节点的 Agent 运行默认会保存会话快照以便后续恢复(除非显式覆盖为 `DELETE`)。
+
+### 插件工具构建器(WorkflowAgentPluginToolsBuilder)
+
+PR #36772 引入了 `WorkflowAgentPluginToolsBuilder` 类(`api/core/workflow/nodes/agent_v2/plugin_tools_builder.py`),负责将 Agent Soul 中的 Dify Plugin Tools 配置转换为 Agent 后端 DTO(`DifyPluginToolsLayerConfig`)。
+
+**主要职责**:
+- 解析 `AgentSoulToolsConfig.dify_tools` 列表(每项为 `AgentSoulDifyToolConfig`)
+- 通过 `ToolManager` 获取工具运行时(`Tool`)并验证声明、凭证和运行时参数
+- 合并工具参数并生成模型可见的 JSON Schema
+- 过滤并规范化凭证(仅允许标量值:str/int/float/bool/None)
+- 构造 `DifyPluginToolConfig` 列表并返回 `DifyPluginToolsLayerConfig`
+
+**错误码**:
+- `agent_tool_declaration_not_found`:工具声明在 Plugin Daemon 中不存在
+- `agent_tool_credential_invalid`:凭证验证失败
+- `agent_tool_config_invalid`:运行时构造失败(如缺少 `runtime` 字段)
+- `agent_tool_runtime_parameter_missing`:必需的隐藏参数缺失
+- `agent_tool_credential_shape_invalid`:凭证包含非标量值(如嵌套对象、列表)
+
+**安全约束**:只有标量凭证值(str/int/float/bool/None)会转发给 Agent 后端;复杂对象(如 OAuth2 token blob)会触发 `agent_tool_credential_shape_invalid` 错误,防止将 Python `repr` 传递给 daemon。
+
+### 会话清理机制
+
+PR #36772 为工作流 Agent 节点引入了完整的会话清理机制,确保 Agent 后端的 suspended 状态在工作流终止时得到妥善清理。
+
+#### CleanupLayerSpec 与持久化
+
+`CleanupLayerSpec` 类用于持久化非凭证层的 Layer 规范(`name`、`type`、`deps`、`metadata`、`config`)。`extract_cleanup_layer_specs()` 函数从当前 `RunComposition` 中提取所有**非凭证层**的规范,排除 `DIFY_PLUGIN_LLM_LAYER_TYPE_ID` 和 `DIFY_PLUGIN_TOOLS_LAYER_TYPE_ID`(因为凭证不跨运行持久化)。
+
+`WorkflowAgentRuntimeSession` 数据库表新增 `composition_layer_specs: LongText` 字段,存储 JSON 编码的 `CleanupLayerSpec` 列表,使清理请求可以重放原始 Layer 图结构(去除凭证层)。
+
+#### build_cleanup_request()
+
+`AgentBackendRunRequestBuilder` 新增 `build_cleanup_request()` 方法,构造仅用于生命周期清理的 `CreateRunRequest`:
+- 从 `composition_layer_specs` 重建 Layer composition(不包含 LLM/tools 层)
+- 使用 `_filter_snapshot_to_specs()` 过滤会话快照,仅保留与清理 composition 名称匹配的层(避免 agenton compositor 的名称顺序验证失败)
+- 设置 `on_exit.default = ExitIntent.DELETE` 以确保清理运行立即释放所有状态
+- `metadata["agent_backend_lifecycle"] = "session_cleanup"` 标记清理运行类型
+
+#### WorkflowAgentSessionCleanupLayer
+
+`WorkflowAgentSessionCleanupLayer`(`api/core/workflow/nodes/agent_v2/session_cleanup_layer.py`)是一个 `GraphEngineLayer` 实现,监听工作流终端事件(`GraphRunSucceededEvent`、`GraphRunPartialSucceededEvent`、`GraphRunFailedEvent`、`GraphRunAbortedEvent`),在工作流结束时对所有 ACTIVE 状态的 Agent 会话执行清理。
+
+**当前实现约束**:`_HTTP_CLEANUP_SUPPORTED` 标志位当前为 `False`,因为 Agent 后端的 `runner.py` 尚未支持 cleanup-only run(仍会强制调用 `run.get_layer("llm")`)。当前清理流程仅通过 `session_store.mark_cleaned()` 将本地会话状态置为 `CLEANED`,让 Agent 后端的 retention TTL 自行释放 suspended 层;一旦 Agent 后端实现 `purpose="cleanup"` 分支,可直接将标志位改为 `True` 启用 HTTP 清理。
+
+### 节点输出检查器(Node Output Inspector)
+
+PR #36772 引入了完整的**节点输出检查器**(Node Output Inspector),提供面向生产者的节点输出视图,替代旧版面向消费者的变量检查器。
+
+#### REST 端点
+
+两组并行的 REST 端点,分别服务于 draft 和 published 运行(共 8 个端点):
+
+**Draft 运行端点**(`/apps/<app_id>/workflows/draft/runs/<run_id>/node-outputs/...`):
+- `GET ...`:全运行快照(所有节点的输出状态)
+- `GET .../<node_id>`:单节点详情(声明的输出 + per-output 状态)
+- `GET .../<node_id>/<output_name>/preview`:单个输出的完整值(含文件签名 URL)
+- `GET .../events`:SSE 事件流(`snapshot` → `node_changed`* → `workflow_run_completed`)
+
+**Published 运行端点**(`/apps/<app_id>/workflows/published/runs/<run_id>/node-outputs/...`):
+- 与 draft 端点形状完全相同,仅 URL 前缀不同,服务实现共用
+
+####SSE 流设计
+
+SSE 端点(`/node-outputs/events`)的流式协议:
+1. 初始 `snapshot` 事件:包含整个运行的初始状态
+2. 每个节点状态变更时发出 `node_changed` 事件(从 Redis pub/sub 驱动)
+3. 工作流终止时发出 `workflow_run_completed` 事件并关闭流
+4. 每 15 个空轮询周期(= 15 秒)发出 `:keepalive` 注释行防止代理超时
+5. 硬超时 1800 秒(30 分钟)强制关闭流(防止 Redis 事件丢失导致僵尸连接)
+
+**错误处理**:node_detail 查询失败时发出 `error` 事件(含 `node_id` 和 `message`),而非断开连接,使前端可以显示部分数据。
+
+### 请求构建器更新
+
+`AgentBackendRunRequestBuilder.build_for_workflow_node()` 的 Layer 构建顺序已更新:
+
+1. Agent Soul 提示 层(如有)
+2. 工作流节点作业提示层
+3. 用户提示层
+4. **Execution Context 层**(`dify.execution_context`)
+5. **History 层**(`pydantic_ai.history`,仅当 `include_history=True`)
+6. **Model 层**(`dify.plugin.llm`,依赖 `execution_context`)
+7. **Tools 层**(`dify.plugin.tools`,仅当 `tools` 非空,依赖 `execution_context`)
+8. Output 层(如有)
+
+**关键变更**:
+- Model 和 Tools 层的 `deps` 字段从 `{"plugin": DIFY_PLUGIN_CONTEXT_LAYER_ID}` 改为 `{"execution_context": DIFY_EXECUTION_CONTEXT_LAYER_ID}`
+- History 层使用保留 ID `DIFY_AGENT_HISTORY_LAYER_ID` 和 type `PYDANTIC_AI_HISTORY_LAYER_TYPE_ID`
+- Tools 层名称固定为 `DIFY_PLUGIN_TOOLS_LAYER_ID = "tools"`
+- `CreateRunRequest` 的顶层 `execution_context` 字段已移除,执行上下文现已完全嵌入 Layer composition
+
+### 数据模型扩展
+
+#### AgentSoulDifyToolConfig
+
+`AgentSoulDifyToolConfig`(`api/models/agent_config_entities.py`)现在是严格类型化的 Pydantic 模型(不再是 `dict[str, Any]`),包含字段:
+- `enabled: bool = True`
+- `provider_type: str = "plugin"`
+- `provider_id: str | None`(兼容旧格式)
+- `plugin_id: str | None` / `provider: str | None`(新格式)
+- `tool_name: str`
+- `credential_type: Literal["api-key", "oauth2", "unauthorized"]`
+- `credential_ref: AgentSoulDifyToolCredentialRef | None`
+- `name: str | None`(保留字段,当前不支持用户重命名)
+- `description: str | None`
+- `runtime_parameters: dict[str, Any]`
+
+**验证逻辑**:
+- `provider_id` 或 `plugin_id + provider` 必须提供其一
+- 凭证类型非 `unauthorized` 时必须提供 `credential_ref.id`
+- `name` 字段暂不支持重命名(如值与 `tool_name` 不同则报错)
+- 旧格式字段(`provider_name`、`tool_parameters`、`credential_id`)在 `@model_validator(mode="before")` 中规范化到新字段
+
+#### WorkflowAgentRuntimeSession
+
+新增 `WorkflowAgentRuntimeSession` 表用于持久化 Agent 会话快照:
+- `tenant_id`, `app_id`, `workflow_id`, `workflow_run_id`, `node_id`, `binding_id`, `agent_id`, `agent_config_snapshot_id`:会话作用域标识
+- `backend_run_id`:对应的 Agent 后端 run ID
+- `session_snapshot: LongText`:Agent 后端返回的会话快照 JSON
+- `composition_layer_specs: LongText`:清理重放需要的 Layer 规范 JSON(默认 `[]`)
+- `status: WorkflowAgentRuntimeSessionStatus`:`ACTIVE`(可恢复)或 `CLEANED`(已清理,不可再用)
+- `cleaned_at: datetime | None`:清理时间戳
+
+**唯一约束**:`(tenant_id, workflow_run_id, node_id, binding_id, agent_id)` 确保每个节点执行作用域至多一条 ACTIVE 会话。
+
+**索引**:
+- `(tenant_id, workflow_run_id, node_id, status)`:用于快速查找待清理会话
+- `backend_run_id`:用于跟踪和审计
+
+### 测试与可观察性增强
+
+PR #36772 对控制台 OpenAPI 文档(`api/openapi/markdown/console-swagger.md`)和服务 API 文档(`service-swagger.md`)进行了大规模更新(+256/-47 行和 +92/-10 行),同步反映新增的节点输出检查器端点和 Agent 配置相关接口的变更。
+
+API 工厂(`api/app_factory.py`)新增 `workflow_node_output_inspector` 蓝图注册,确保节点输出检查器端点在生产环境可用。

[Accept] [Edit] [Decline]

How did I do? Any feedback?

@FFXN FFXN force-pushed the feat/dev-snippet-fronted branch from 2424f53 to df83e26 Compare May 28, 2026 07:45
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels May 28, 2026
@github-actions github-actions Bot removed the web This relates to changes on the web. label May 28, 2026
@FFXN FFXN changed the title Feat: dev snippet fronted feat: dev snippet fronted May 28, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Pyrefly Diff

base → PR
--- /tmp/pyrefly_base.txt	2026-05-28 07:47:06.055578332 +0000
+++ /tmp/pyrefly_pr.txt	2026-05-28 07:46:51.943351335 +0000
@@ -1,7 +1,3 @@
-ERROR Could not import `CleanupLayerSpec` from `clients.agent_backend.request_builder` [missing-module-attribute]
-  --> clients/agent_backend/__init__.py:41:5
-ERROR Could not import `extract_cleanup_layer_specs` from `clients.agent_backend.request_builder` [missing-module-attribute]
-  --> clients/agent_backend/__init__.py:42:5
 ERROR `str` is not assignable to `Literal['advanced-chat', 'agent-chat', 'all', 'channel', 'chat', 'completion', 'workflow']` [bad-assignment]
   --> controllers/console/app/app.py:69:104
 ERROR Argument `str | None` is not assignable to parameter `language` with type `str` in function `services.account_service.AccountService.send_email_register_email` [bad-argument-type]
@@ -88,12 +84,6 @@
   --> core/tools/utils/web_reader_tool.py:66:35
 ERROR `list[Never]` is not assignable to attribute `tools` with type `Never` [bad-assignment]
    --> core/tools/workflow_as_tool/provider.py:238:26
-ERROR Unexpected keyword argument `session_snapshot` in function `core.workflow.nodes.agent_v2.runtime_request_builder.WorkflowAgentRuntimeBuildContext.__init__` [unexpected-keyword]
-   --> core/workflow/nodes/agent_v2/agent_node.py:187:25
-ERROR Object of class `AgentBackendRunRequestBuilder` has no attribute `build_cleanup_request` [missing-attribute]
-   --> core/workflow/nodes/agent_v2/session_cleanup_layer.py:161:19
-ERROR Could not import `CleanupLayerSpec` from `clients.agent_backend.request_builder` [missing-module-attribute]
- --> core/workflow/nodes/agent_v2/session_store.py:9:51
 ERROR Cannot set item in `dict[str, dict[str, crontab | str]]` [unsupported-operation]
    --> extensions/ext_celery.py:176:63
 ERROR Cannot set item in `dict[str, dict[str, crontab | str]]` [unsupported-operation]
@@ -1992,8 +1982,6 @@
    --> tests/test_containers_integration_tests/trigger/test_trigger_e2e.py:857:21
 ERROR Argument `Literal['unsupported_language']` is not assignable to parameter `language` with type `CodeLanguage` in function `core.helper.code_executor.code_executor.CodeExecutor.execute_workflow_code_template` [bad-argument-type]
   --> tests/test_containers_integration_tests/workflow/nodes/code_executor/test_code_executor.py:10:62
-ERROR Object of class `AgentBackendRunRequestBuilder` has no attribute `build_cleanup_request` [missing-attribute]
-  --> tests/unit_tests/clients/agent_backend/test_cleanup_composition_compositor_integration.py:67:23
 ERROR Argument `dict[str, object]` is not assignable to parameter `configs` with type `Mapping[str, LayerConfigInput] | None` in function `agenton.compositor.core.Compositor._create_run` [bad-argument-type]
   --> tests/unit_tests/clients/agent_backend/test_cleanup_composition_compositor_integration.py:97:17
 ERROR Cannot index into `bool` [bad-index]
@@ -2008,11 +1996,6 @@
   --> tests/unit_tests/clients/agent_backend/test_event_adapter.py:53:12
 ERROR `None` is not subscriptable [unsupported-operation]
   --> tests/unit_tests/clients/agent_backend/test_event_adapter.py:53:12
-ERROR Object of class `LayerConfig` has no attribute `user_id`
-ERROR Object of class `LayerConfig` has no attribute `plugin_id`
-ERROR Object of class `LayerConfig` has no attribute `tools`
-ERROR Cannot index into `object` [bad-index]
-   --> tests/unit_tests/clients/agent_backend/test_request_builder.py:164:12
 ERROR Expected a callable, got `None` [not-callable]
   --> tests/unit_tests/commands/test_clean_expired_messages.py:33:9
 ERROR Expected a callable, got `None` [not-callable]
@@ -2157,6 +2140,22 @@
   --> tests/unit_tests/controllers/console/test_workspace_members.py:16:5
 ERROR `SimpleNamespace` is not assignable to attribute `_current_tenant` with type `Tenant | None` [bad-assignment]
   --> tests/unit_tests/controllers/console/test_workspace_members.py:73:43
+ERROR Object of class `Exception` has no attribute `code` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:119:24
+ERROR Object of class `Exception` has no attribute `code` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:183:16
+ERROR Object of class `Exception` has no attribute `description` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:184:56
+ERROR Object of class `Exception` has no attribute `code` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:263:28
+ERROR Object of class `Exception` has no attribute `description` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:264:67
+ERROR Object of class `Exception` has no attribute `code` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:288:28
+ERROR Object of class `Exception` has no attribute `code` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:364:28
+ERROR Object of class `Exception` has no attribute `description` [missing-attribute]
+   --> tests/unit_tests/controllers/console/test_wraps.py:365:48
 ERROR `SimpleNamespace` is not assignable to attribute `db` with type `SQLAlchemy` [bad-assignment]
   --> tests/unit_tests/controllers/files/test_image_preview.py:23:17
 ERROR `SimpleNamespace` is not assignable to attribute `request` with type `Request` [bad-assignment]
@@ -5666,8 +5665,6 @@
    --> tests/unit_tests/core/workflow/nodes/agent_v2/test_plugin_tools_builder.py:151:12
 ERROR `not in` is not supported between `Literal['region']` and `None` [not-iterable]
    --> tests/unit_tests/core/workflow/nodes/agent_v2/test_plugin_tools_builder.py:151:12
-ERROR Argument `FakePluginToolsBuilder` is not assignable to parameter `plugin_tools_builder` with type `WorkflowAgentPluginToolsBuilder | None` in function `core.workflow.nodes.agent_v2.runtime_request_builder.WorkflowAgentRuntimeRequestBuilder.__init__` [bad-argument-type]
-   --> tests/unit_tests/core/workflow/nodes/agent_v2/test_runtime_request_builder.py:227:30
 ERROR Argument `object` is not assignable to parameter `status` with type `Literal['cancelled', 'failed', 'paused', 'running', 'succeeded']` in function `dify_agent.protocol.schemas.RunStatusResponse.__init__` [bad-argument-type]
    --> tests/unit_tests/core/workflow/nodes/agent_v2/test_session_cleanup_layer.py:121:20
 ERROR Class member `_WaitableFakeAgentBackendRunClient.stream_events` overrides parent class `FakeAgentBackendRunClient` in an inconsistent manner [bad-override]
@@ -5676,8 +5673,6 @@
    --> tests/unit_tests/core/workflow/nodes/agent_v2/test_session_cleanup_layer.py:154:30
 ERROR Argument `_WaitableFakeAgentBackendRunClient` is not assignable to parameter `agent_backend_client` with type `AgentBackendRunClient | None` in function `core.workflow.nodes.agent_v2.session_cleanup_layer.WorkflowAgentSessionCleanupLayer.__init__` [bad-argument-type]
    --> tests/unit_tests/core/workflow/nodes/agent_v2/test_session_cleanup_layer.py:360:30
-ERROR Could not import `CleanupLayerSpec` from `clients.agent_backend.request_builder` [missing-module-attribute]
-  --> tests/unit_tests/core/workflow/nodes/agent_v2/test_session_store.py:19:51
 ERROR Object of class `FromClause` has no attribute `create` [missing-attribute]
   --> tests/unit_tests/core/workflow/nodes/agent_v2/test_session_store.py:66:5
 ERROR Object of class `FromClause` has no attribute `drop` [missing-attribute]

@github-actions
Copy link
Copy Markdown
Contributor

Pyrefly Type Coverage

Metric Base PR Delta
Type coverage 45.99% 46.00% +0.01%
Strict coverage 45.52% 45.53% +0.01%
Typed symbols 24,773 24,785 +12
Untyped symbols 29,392 29,393 +1
Modules 2754 2754 0

@FFXN FFXN merged commit 42ccc7d into deploy/dev May 28, 2026
4 of 5 checks passed
@FFXN FFXN deleted the feat/dev-snippet-fronted branch May 28, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat:webapp Ready-to-use AI web app. Also the "Preview" / "Debug & Preview" inside the orchestrate page. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.