Skip to content

[WIP]refactor!: redesign pipeline with chain-based engine and NodeStar system#4960

Draft
Raven95676 wants to merge 11 commits intoAstrBotDevs:masterfrom
Raven95676:next
Draft

[WIP]refactor!: redesign pipeline with chain-based engine and NodeStar system#4960
Raven95676 wants to merge 11 commits intoAstrBotDevs:masterfrom
Raven95676:next

Conversation

@Raven95676
Copy link
Member

@Raven95676 Raven95676 commented Feb 8, 2026

impl #1948

Caution

这是一个破坏性变更

Need More and More Test

Modifications / 改动点

用chain-based线性流水线替代原有 9 阶段洋葱模型pipeline,作为面向workflow扩展的渐进式重构

新增 Chain 系统:

  • NodeStar:可挂载到 Chain 中的处理节点基类,process() 返回 NodeResult(CONTINUE/STOP/WAIT/SKIP)

  • ChainConfig:DB 持久化的 Chain 配置,定义节点顺序与匹配规则

  • ChainExecutor:顺序执行 Chain 节点,通过 NodeContext/NodePacket 实现节点间数据传递

  • WaitRegistry:多轮等待/恢复机制

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果


Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This WIP PR introduces a new chain-based pipeline execution architecture (NodeStar + ChainConfig/Router/Executor/WaitRegistry) to replace the legacy multi-stage “onion” pipeline, and updates the dashboard to manage “Chain Routing” instead of session-based rule management.

Changes:

  • Replace legacy pipeline stages/scheduler with a chain-based execution engine (routing, node contexts/packets, wait/resume, runtime feature flags).
  • Introduce NodeStar plugin model + node-scoped config schemas and several builtin pipeline nodes (agent/stt/tts/t2i/knowledge_base/file_extract/content_safety).
  • Update WebUI routes/navigation/i18n and some dashboard APIs to align with chain/config_id routing.

Reviewed changes

Copilot reviewed 144 out of 145 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
dashboard/src/router/MainRoutes.ts Rename route to ChainManagement and update path/component.
dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts Update sidebar entry to Chain Routing.
dashboard/src/i18n/translations.ts Swap session-management module for chain-management module.
dashboard/src/i18n/locales/zh-CN/features/session-management.json Remove legacy session management locale.
dashboard/src/i18n/locales/zh-CN/features/config-metadata.json Remove legacy STT/TTS/file_extract metadata keys.
dashboard/src/i18n/locales/zh-CN/features/chain-management.json Add chain-management locale strings (ZH).
dashboard/src/i18n/locales/zh-CN/core/navigation.json Rename nav key to chainManagement (ZH).
dashboard/src/i18n/locales/en-US/features/session-management.json Remove legacy session management locale.
dashboard/src/i18n/locales/en-US/features/config-metadata.json Remove legacy STT/TTS/file_extract metadata keys.
dashboard/src/i18n/locales/en-US/features/chain-management.json Add chain-management locale strings (EN).
dashboard/src/i18n/locales/en-US/core/navigation.json Rename nav key to chainManagement (EN).
dashboard/src/i18n/loader.ts Load chain-management module instead of session-management.
dashboard/src/components/shared/ObjectEditor.vue Add “lock template keys” behavior and conditional custom key editing.
dashboard/src/components/chat/StandaloneChat.vue Remove config-id prop wiring to ChatInput.
dashboard/src/components/chat/ChatInput.vue Remove ConfigSelector and related props/computed logic.
dashboard/src/components/RuleEditor.vue Add rule editor UI for chain match rules.
astrbot/dashboard/server.py Wire up ChainManagementRoute (via routes import).
astrbot/dashboard/routes/t2i.py Reload pipeline executors after template changes.
astrbot/dashboard/routes/cron.py Include config_id in cron job payload.
astrbot/dashboard/routes/config.py Shift API naming/behavior toward config_id and remove UMOP routing endpoints.
astrbot/dashboard/routes/chat.py Remove UMOP config-route cleanup on webchat session delete.
astrbot/dashboard/routes/init.py Export ChainManagementRoute; remove SessionManagementRoute export.
astrbot/core/utils/session_waiter.py Disallow SessionWaiter usage in NodeStar/chain context.
astrbot/core/utils/migra_helper.py Add migration hook for chain configs and refactor UMOP router creation.
astrbot/core/umop_config_router.py Rename mapping to umop_to_config_id and update related APIs.
astrbot/core/tools/cron_tools.py Add config_id to tool-originated cron payload.
astrbot/core/star/star_manager.py Load optional node config schema for NodeStar plugins.
astrbot/core/star/star_base.py New shared Star base class extracted from star/init.py.
astrbot/core/star/star.py Add node_schema field to StarMetadata and adjust imports.
astrbot/core/star/session_plugin_manager.py Remove legacy per-session plugin enable/disable manager.
astrbot/core/star/session_llm_manager.py Remove legacy per-session service enable/disable manager.
astrbot/core/star/register/star.py Fix import path for StarMetadata/star_map after refactor.
astrbot/core/star/node_star.py Introduce NodeStar base class + NodeResult + streaming collector helper.
astrbot/core/star/modality.py Add modality extraction utilities for routing.
astrbot/core/star/init.py Re-export Star/NodeStar/Modality APIs and clean up module structure.
astrbot/core/provider/manager.py Deprecate legacy provider switching APIs and adjust STT/TTS resolution.
astrbot/core/platform/sources/webchat/webchat_adapter.py Only set enable_streaming extra if explicitly provided by client payload.
astrbot/core/pipeline/whitelist_check/stage.py Remove legacy stage implementation (replaced by AccessController).
astrbot/core/pipeline/waking_check/stage.py Remove legacy waking stage implementation.
astrbot/core/pipeline/system/star_yield.py Add compatibility layer for legacy Star async-generator (yield) handlers.
astrbot/core/pipeline/system/session_utils.py Extract unique-session-id builder helpers.
astrbot/core/pipeline/system/rate_limit.py Add chain-compatible fixed-window rate limiter.
astrbot/core/pipeline/system/event_preprocessor.py Add system-level preprocessing (admins/unique session/path mapping).
astrbot/core/pipeline/system/access_control.py Add chain-compatible whitelist check.
astrbot/core/pipeline/system/init.py Export new system pipeline utilities.
astrbot/core/pipeline/stage.py Remove legacy Stage abstraction.
astrbot/core/pipeline/session_status_check/stage.py Remove legacy session status stage.
astrbot/core/pipeline/scheduler.py Remove legacy PipelineScheduler.
astrbot/core/pipeline/rate_limit_check/stage.py Remove legacy rate limit stage.
astrbot/core/pipeline/process_stage/stage.py Remove legacy processing stage.
astrbot/core/pipeline/process_stage/method/star_request.py Remove legacy star request sub-stage.
astrbot/core/pipeline/process_stage/method/agent_request.py Remove legacy agent request sub-stage.
astrbot/core/pipeline/preprocess_stage/stage.py Remove legacy preprocess stage (STT/path mapping/ack emoji, etc.).
astrbot/core/pipeline/engine/wait_registry.py Add wait/resume registry for multi-turn node WAIT behavior.
astrbot/core/pipeline/engine/rule_matcher.py Add match rule evaluation engine (umo/modality/text regex).
astrbot/core/pipeline/engine/router.py Add ChainRouter loading configs from DB and routing events to chains.
astrbot/core/pipeline/engine/node_context.py Add node context stack + NodePacket model.
astrbot/core/pipeline/engine/chain_runtime_flags.py Add per-chain runtime feature toggles (llm/stt/tts/t2i).
astrbot/core/pipeline/engine/chain_executor.py Add sequential chain executor with node init, outputs, and WAIT support.
astrbot/core/pipeline/engine/chain_config.py Add DB model + runtime ChainConfig and node normalization/UUID strategy.
astrbot/core/pipeline/context_utils.py Remove legacy call_handler implementation, keep hook calls.
astrbot/core/pipeline/context.py Adjust PipelineContext to new executor model and typing exports.
astrbot/core/pipeline/content_safety_check/strategies/strategy.py Remove legacy content safety strategy selector (moved to builtin node).
astrbot/core/pipeline/content_safety_check/strategies/keywords.py Remove legacy keywords strategy.
astrbot/core/pipeline/content_safety_check/strategies/baidu_aip.py Remove legacy Baidu AIP strategy.
astrbot/core/pipeline/content_safety_check/strategies/init.py Remove legacy strategy base class.
astrbot/core/pipeline/content_safety_check/stage.py Remove legacy content safety stage.
astrbot/core/pipeline/agent/types.py Add AgentRunOutcome for new agent execution flow.
astrbot/core/pipeline/agent/third_party.py Refactor third-party agent runner into executor returning AgentRunOutcome.
astrbot/core/pipeline/agent/runner_config.py Add node-config-based agent runner resolution helpers.
astrbot/core/pipeline/agent/executor.py Add unified AgentExecutor (internal + third-party) with chain runtime flags.
astrbot/core/pipeline/agent/init.py Export AgentExecutor.
astrbot/core/pipeline/init.py Remove legacy stage ordering exports.
astrbot/core/persona_mgr.py Allow resolving default persona via config_id (chain-routed config).
astrbot/core/message/message_event_result.py Add collect_streaming_result helper.
astrbot/core/event_bus.py Route events via ChainRouter + resume via WaitRegistry; dispatch PipelineExecutor.
astrbot/core/db/migration/migra_45_to_46.py Update migration naming and UMOP mapping keys (config_id).
astrbot/core/cron/manager.py Resolve config by config_id from cron payload for permissions.
astrbot/core/core_lifecycle.py Replace scheduler with PipelineExecutor mapping + initialize ChainRouter.
astrbot/core/config/node_config.py Add persisted node-scoped config (AstrBotNodeConfig) keyed by node/chain/uuid.
astrbot/core/config/init.py Export AstrBotNodeConfig.
astrbot/core/computer/tools/shell.py Pass config_id into sandbox booter resolution.
astrbot/core/computer/tools/python.py Pass config_id into sandbox booter resolution.
astrbot/core/computer/tools/fs.py Pass config_id into sandbox booter resolution.
astrbot/core/computer/computer_client.py Resolve sandbox config via config_id.
astrbot/core/astr_main_agent_resources.py Resolve config via chain config_id and remove session-scoped KB config.
astrbot/core/astr_agent_tool_exec.py Resolve provider id with event-aware selection.
astrbot/builtin_stars/web_searcher/main.py Resolve config via chain config_id; adjust Baidu MCP init signature.
astrbot/builtin_stars/tts/metadata.yaml Add builtin TTS node metadata.
astrbot/builtin_stars/tts/main.py Add TTS node implementation (chain runtime flag + provider resolution).
astrbot/builtin_stars/tts/_node_config_schema.json Add TTS node config schema.
astrbot/builtin_stars/t2i/metadata.yaml Add builtin T2I node metadata.
astrbot/builtin_stars/t2i/main.py Add T2I node implementation (chain runtime flag + template selection).
astrbot/builtin_stars/t2i/_node_config_schema.json Add T2I node config schema.
astrbot/builtin_stars/stt/metadata.yaml Add builtin STT node metadata.
astrbot/builtin_stars/stt/main.py Add STT node implementation (chain runtime flag + provider resolution).
astrbot/builtin_stars/stt/_node_config_schema.json Add STT node config schema.
astrbot/builtin_stars/session_controller/main.py Resolve config via chain config_id for behavior.
astrbot/builtin_stars/knowledge_base/metadata.yaml Add knowledge-base retrieval node metadata.
astrbot/builtin_stars/knowledge_base/main.py Add knowledge-base retrieval node implementation.
astrbot/builtin_stars/knowledge_base/_node_config_schema.json Add KB node config schema.
astrbot/builtin_stars/file_extract/metadata.yaml Add file extraction node metadata.
astrbot/builtin_stars/file_extract/main.py Add file extraction node implementation.
astrbot/builtin_stars/file_extract/_node_config_schema.json Add file extraction node config schema.
astrbot/builtin_stars/content_safety/strategies.py Add content safety strategies for node-based checks.
astrbot/builtin_stars/content_safety/requirements.txt Add plugin-level dependency list (baidu-aip).
astrbot/builtin_stars/content_safety/metadata.yaml Add content safety node metadata.
astrbot/builtin_stars/content_safety/main.py Add content safety node implementation (input/output checks).
astrbot/builtin_stars/content_safety/_node_config_schema.json Add content safety node config schema.
astrbot/builtin_stars/builtin_commands/main.py Add STT command and reorder built-in commands.
astrbot/builtin_stars/builtin_commands/commands/tts.py Change TTS toggle to per-chain runtime flag.
astrbot/builtin_stars/builtin_commands/commands/t2i.py Change T2I toggle to per-chain runtime flag.
astrbot/builtin_stars/builtin_commands/commands/stt.py Add STT toggle command (per-chain runtime flag).
astrbot/builtin_stars/builtin_commands/commands/llm.py Change LLM toggle to per-chain runtime flag.
astrbot/builtin_stars/builtin_commands/commands/conversation.py Make conversation commands chain/node-aware for runner/provider/persona.
astrbot/builtin_stars/builtin_commands/commands/admin.py Resolve config via chain config_id for whitelist ops.
astrbot/builtin_stars/builtin_commands/commands/_node_binding.py Add helpers to locate chain nodes and node configs.
astrbot/builtin_stars/builtin_commands/commands/init.py Export STTCommand.
astrbot/builtin_stars/astrbot/main.py Resolve config via chain config_id; adjust active reply provider selection.
astrbot/builtin_stars/astrbot/long_term_memory.py Make provider selection event-aware for image captioning.
astrbot/builtin_stars/agent/metadata.yaml Add builtin agent node metadata.
astrbot/builtin_stars/agent/main.py Add agent node implementation using AgentExecutor.
astrbot/builtin_stars/agent/_node_config_schema.json Add agent node config schema (runner + provider/persona overrides).
astrbot/api/star/init.py Export NodeStar/NodeResult in public API.
Comments suppressed due to low confidence (3)

astrbot/builtin_stars/astrbot/main.py:12

  • This class does not call Star.init during initialization. (Main.init may be missing a call to a base class init)
class Main(star.Star):

astrbot/builtin_stars/web_searcher/main.py:20

  • This class does not call Star.init during initialization. (Main.init may be missing a call to a base class init)
    astrbot/builtin_stars/builtin_commands/main.py:21
  • This class does not call Star.init during initialization. (Main.init may be missing a call to a base class init)
class Main(star.Star):

Comment on lines +292 to +299
if (hasTemplateSchema.value && !allowCustomKeys.value) {
for (const [key, template] of Object.entries(templateSchema.value)) {
const rawValue = props.modelValue[key]
let _type = template.type || (typeof rawValue === 'object' ? 'json' : typeof rawValue)
let _value = _type === 'json' ? JSON.stringify(rawValue) : rawValue
if (_value === undefined || _value === null) {
_value = template.default !== undefined ? template.default : getDefaultValueForType(_type)
}
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When template keys are locked, null values get stringified to the literal string "null" (because typeof null === 'object'), so the default value fallback won't run. This can persist invalid values and break type handling. Consider checking rawValue for null/undefined before inferring type / JSON.stringify, and fall back to template.default (or getDefaultValueForType) when rawValue is null.

Copilot uses AI. Check for mistakes.
Comment on lines +446 to +451
config_id = self.acm.create_conf(name=name, config=config)
return (
Response()
.ok(message="创建成功", data={"config_id": config_id})
.__dict__
)
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint changes the response payload key from "conf_id" to "config_id". Since other endpoints still accept legacy request keys ("id"), consider returning both keys (or keeping "conf_id" as an alias) to avoid breaking existing dashboard/client code that expects "conf_id".

Copilot uses AI. Check for mistakes.
Comment on lines 836 to +850
async def post_astrbot_configs(self):
data = await request.json
config = data.get("config", None)
conf_id = data.get("conf_id", None)
config_id = data.get("config_id")

try:
# 不更新 provider_sources, provider, platform
# 这些配置有单独的接口进行更新
if conf_id == "default":
if config_id == "default":
no_update_keys = ["provider_sources", "provider", "platform"]
for key in no_update_keys:
config[key] = self.acm.default_conf[key]

await self._save_astrbot_configs(config, conf_id)
await self.core_lifecycle.reload_pipeline_scheduler(conf_id)
await self._save_astrbot_configs(config, config_id)
await self.core_lifecycle.reload_pipeline_executor(config_id)
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post_astrbot_configs now only reads "config_id" from the request body. Other endpoints in this file accept legacy keys ("conf_id"/"id"); without a fallback here, older clients will start failing with "配置文件 None 不存在". Consider accepting "conf_id" (and/or "id") as an alias, similar to delete_abconf/update_abconf.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
baidu-aip No newline at end of file
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a new dependency (baidu-aip). The PR checklist indicates no new dependencies were introduced; please update the checklist/PR description accordingly and ensure the project’s dependency installation flow will actually install this plugin requirement in production deployments.

Copilot uses AI. Check for mistakes.

async def _post_send(self):
"""调度器会在执行 send() 后调用该方法 deprecated in v3.5.18"""
async def _post_send(self, message: MessageChain | None = None, **_):
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overridden method signature does not match call, where it is passed an argument named 'stream'. Overriding method method QQOfficialMessageEvent._post_send matches the call.
Overridden method signature does not match call, where it is passed an argument named 'stream'. Overriding method method QQOfficialMessageEvent._post_send matches the call.

Copilot uses AI. Check for mistakes.
import re
from typing import Any

import astrbot.core.message.components as Comp
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module 'astrbot.core.message.components' is imported with both 'import' and 'import from'.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFC] 关于将pipeline重构为workflow的草案

1 participant