feat: 工具系统迁移 + 重型插件骨架 + 前端交互增强

- 工具系统从 kilostar/plugin/tool_plugin/ 迁移到 data/toolset/(manifest.json 声明式)
- 新增 plugin_runtime 模块:BaseOrganization / GlobalPluginManager / loader / tool_bridge
- 新增 org_task + org_task_event 表及 DAO(alembic 0009)
- 新增 /api/v1/plugin 路由(submit/status/stream/install/reload)
- 新增 data/plugin/example_dept 示例重型插件
- regulatory_node 支持聊天历史上下文注入
- send_file 改为 artifact 存盘 + SSE 推送下载链接
- 前端 WorkflowFileCard 组件 + ToolSettings README 渲染
- utils 整理:合并 access/role_check、standalone_proxy→ray_compat、删除废弃模块
- 项目结构文档移至 docs/STRUCTURE.md 并详细展开

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 05:20:00 +00:00
parent 9b73ae4db4
commit 6d658b4f4d
74 changed files with 2591 additions and 1308 deletions
@@ -14,7 +14,7 @@
from typing import Union, overload
from kilostar.utils.standalone_proxy import actor_class
from kilostar.utils.ray_compat import actor_class
from kilostar.core.individual.consciousness_node.template import (
ConsciousnessNodeDeps,
ForregulatoryNode,
@@ -29,7 +29,7 @@ from kilostar.core.global_state_machine.global_state_machine import GlobalStateM
from kilostar.core.global_state_machine.model_provider.base_provider import Provider
from kilostar.adapter.model_adapter.agent_factory import AgentFactory
from kilostar.utils.ray_hook import ray_actor_hook
from kilostar.utils.i18n import agent_prompt
from kilostar.utils.prompts import agent_prompt
@actor_class
@@ -13,7 +13,7 @@
# limitations under the License.
from pydantic_ai import Agent, RunContext
from kilostar.utils.standalone_proxy import actor_class
from kilostar.utils.ray_compat import actor_class
from kilostar.core.global_state_machine.global_state_machine import GlobalStateMachine
from kilostar.core.global_state_machine.model_provider.base_provider import Provider
from kilostar.adapter.model_adapter.agent_factory import AgentFactory
@@ -22,7 +22,7 @@ from kilostar.core.individual.control_node.template import (
ForWorkflowInput,
ControlNodeDeps,
)
from kilostar.utils.i18n import agent_prompt
from kilostar.utils.prompts import agent_prompt
@actor_class
@@ -15,7 +15,7 @@
import asyncio
import datetime
from typing import Union
from kilostar.utils.standalone_proxy import actor_class
from kilostar.utils.ray_compat import actor_class
from kilostar.adapter.model_adapter.agent_factory import AgentFactory
from kilostar.core.global_state_machine.global_state_machine import GlobalStateMachine
from kilostar.core.global_state_machine.model_provider import Provider
@@ -25,7 +25,7 @@ from kilostar.core.individual.regulatory_node.template import (
MessageResponse
)
from pydantic_ai import RunContext, Agent
from kilostar.utils.i18n import agent_prompt
from kilostar.utils.prompts import agent_prompt
@actor_class
@@ -111,15 +111,20 @@ class RegulatoryNode:
)
return prompt
async def working(self, payload: MessageRequest) -> Union[MessageResponse, None]:
async def working(
self,
payload: MessageRequest,
message_history: list | None = None,
) -> Union[MessageResponse, None]:
"""working方法,是节点唯一的调用方法,对_run函数的结果进行判断并返回最终回复
Args:
payload: 消息载荷,包含所有信息
message_history: pydantic-ai ``ModelMessage`` 列表,传入历史让多轮对话连贯
Returns:
MessageResponse 或 None,监控节点对用户的结构化回复
"""
return await self._run(payload)
return await self._run(payload, message_history=message_history)
_CHAT_INSTRUCTIONS = (
"你是 kilostar 智能助手。你现在处于【直接对话模式】,请直接回答用户的问题。\n"
@@ -130,7 +135,12 @@ class RegulatoryNode:
"4. 回复应当完整、有帮助,避免过于简短。\n"
)
async def stream_working(self, payload: MessageRequest, token_queue: "asyncio.Queue") -> None:
async def stream_working(
self,
payload: MessageRequest,
token_queue: "asyncio.Queue",
message_history: list | None = None,
) -> None:
"""流式对话:完整执行 agent graph(含工具调用),逐 token 推送文本到 queue。
使用 event_stream_handler 回调拿到每个 text delta,保证工具调用后
@@ -167,6 +177,7 @@ class RegulatoryNode:
output_type=str,
instructions=self._CHAT_INSTRUCTIONS,
event_stream_handler=_stream_handler,
message_history=message_history,
)
except Exception as e:
self.logger.exception(f"RegulatoryNode.stream_working failed: {e}")
@@ -175,7 +186,9 @@ class RegulatoryNode:
await token_queue.put(None)
async def _run(
self, payload: MessageRequest
self,
payload: MessageRequest,
message_history: list | None = None,
) -> Union[MessageResponse, None]:
platform = payload.platform
user_name = payload.user_name
@@ -187,8 +200,11 @@ class RegulatoryNode:
user_name=user_name,
time=time_str
)
agent_response = await self.agent.run(user_prompt=message,
deps=deps,)
agent_response = await self.agent.run(
user_prompt=message,
deps=deps,
message_history=message_history,
)
response: MessageResponse = agent_response.output
response.platform = platform
response.platform_id = payload.platform_id